Write leaf pages for a table, returns root page. rowids must be sequential starting from 1 (or single-row PK text).
| 1186 | // Write leaf pages for a table, returns root page. |
| 1187 | // rowids must be sequential starting from 1 (or single-row PK text). |
| 1188 | static uint32_t write_table_btree(FILE *fp, uint32_t *next_page, const uint8_t **records, |
| 1189 | const int *record_lens, const int64_t *rowids, int count, |
| 1190 | bool first_is_page1) { |
| 1191 | if (count == 0) { |
| 1192 | // Empty table: write a single empty leaf page |
| 1193 | *next_page = cbm_skip_pending_byte(*next_page); |
| 1194 | uint32_t pnum = (*next_page)++; |
| 1195 | uint8_t page[CBM_PAGE_SIZE]; |
| 1196 | memset(page, 0, CBM_PAGE_SIZE); |
| 1197 | int hdr = first_is_page1 ? SQLITE_HEADER_SIZE : 0; |
| 1198 | page[hdr] = BTREE_LEAF_TABLE; // leaf table |
| 1199 | put_u16(page + hdr + HDR_FREEBLOCK_OFF, 0); // no freeblocks |
| 1200 | put_u16(page + hdr + HDR_CELLCOUNT_OFF, 0); // 0 cells |
| 1201 | put_u16(page + hdr + HDR_CONTENT_OFF, (uint16_t)CBM_PAGE_SIZE); // content at end of page |
| 1202 | page[hdr + HDR_FRAGBYTES_OFF] = 0; // 0 fragmented bytes |
| 1203 | (void)fseek(fp, (long)(pnum - SKIP_ONE) * CBM_PAGE_SIZE, SEEK_SET); |
| 1204 | (void)fwrite(page, SKIP_ONE, CBM_PAGE_SIZE, fp); |
| 1205 | return pnum; |
| 1206 | } |
| 1207 | |
| 1208 | PageBuilder pb; |
| 1209 | pb_init(&pb, fp, *next_page, false); |
| 1210 | pb.page1_offset = first_is_page1 ? SQLITE_HEADER_SIZE : 0; |
| 1211 | pb.ptr_offset = pb.page1_offset + BTREE_HEADER_SIZE; |
| 1212 | |
| 1213 | for (int i = 0; i < count; i++) { |
| 1214 | pb_add_table_cell_with_flush(&pb, rowids[i], records[i], record_lens[i], |
| 1215 | i > 0 ? rowids[i - SKIP_ONE] : 0); |
| 1216 | } |
| 1217 | |
| 1218 | return pb_finalize_table(&pb, next_page, rowids[count - SKIP_ONE]); |
| 1219 | } |
| 1220 | |
| 1221 | // Promote the last cell from current page to separator, un-add it, and flush. |
| 1222 | static bool pb_promote_and_flush(PageBuilder *pb, uint8_t **cells, int *cell_lens, int prev_idx) { |
no test coverage detected