MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / pb_flush_leaf

Function pb_flush_leaf

internal/cbm/sqlite_writer.c:490–542  ·  view source on GitHub ↗

Flush current leaf page to file

Source from the content-addressed store, hash-verified

488
489// Flush current leaf page to file
490static void pb_flush_leaf(PageBuilder *pb) {
491 if (pb->cell_count == 0) {
492 return;
493 }
494
495 int hdr = pb->page1_offset;
496 // Write leaf page header
497 pb->page[hdr + 0] = pb->is_index ? BTREE_LEAF_INDEX : BTREE_LEAF_TABLE; // leaf flag
498 put_u16(pb->page + hdr + HDR_FREEBLOCK_OFF, 0); // first freeblock
499 put_u16(pb->page + hdr + HDR_CELLCOUNT_OFF, (uint16_t)pb->cell_count);
500 put_u16(pb->page + hdr + HDR_CONTENT_OFF, (uint16_t)pb->content_offset);
501 pb->page[hdr + HDR_FRAGBYTES_OFF] = 0; // fragmented free bytes
502
503 // Write page to file. Skip the pending byte page (SQLite reserved).
504 pb->next_page = cbm_skip_pending_byte(pb->next_page);
505 uint32_t page_num = pb->next_page;
506 long offset = (long)(page_num - SKIP_ONE) * CBM_PAGE_SIZE;
507 (void)fseek(pb->fp, offset, SEEK_SET);
508 (void)fwrite(pb->page, SKIP_ONE, CBM_PAGE_SIZE, pb->fp);
509
510 // Record this leaf for interior page building
511 if (pb->leaf_count >= pb->leaf_cap) {
512 int old_cap = pb->leaf_cap;
513 pb->leaf_cap = old_cap == 0 ? INITIAL_LEAF_CAP : old_cap * GROWTH_FACTOR;
514 void *tmp = realloc(pb->leaves, (size_t)pb->leaf_cap * sizeof(PageRef));
515 if (!tmp) {
516 /* Leave a CONSISTENT empty state: leaf_count stale at >=1 with a
517 * NULL leaves array walked pb_finalize_* straight into
518 * leaves[0] (null deref, clang-analyzer traced it) whenever the
519 * final cell block was already flushed. Empty state routes every
520 * finalize path to its existing root=0 failure return. */
521 free(pb->leaves);
522 pb->leaves = NULL;
523 pb->leaf_count = 0;
524 pb->leaf_cap = 0;
525 return;
526 }
527 pb->leaves = (PageRef *)tmp;
528 /* Zero-init new slots */
529 memset(&pb->leaves[old_cap], 0, ((size_t)pb->leaf_cap - (size_t)old_cap) * sizeof(PageRef));
530 }
531 pb->leaves[pb->leaf_count].page_num = page_num;
532 // max_key is set by caller before flush
533 pb->leaf_count++;
534
535 // Reset for next page
536 pb->next_page++;
537 pb->cell_count = 0;
538 pb->content_offset = CBM_PAGE_SIZE;
539 pb->page1_offset = 0; // only page 1 has the 100-byte header
540 pb->ptr_offset = BTREE_HEADER_SIZE; // standard B-tree header size for non-page-1
541 memset(pb->page, 0, CBM_PAGE_SIZE);
542}
543
544// Check if a cell of given size fits in the current page
545static bool pb_cell_fits(PageBuilder *pb, int cell_len) {

Callers 4

pb_finalize_tableFunction · 0.85
pb_promote_and_flushFunction · 0.85
write_index_btreeFunction · 0.85

Calls 2

put_u16Function · 0.85
cbm_skip_pending_byteFunction · 0.85

Tested by

no test coverage detected