--- Overflow page writer --- Writes overflow pages for payload bytes that exceed local storage. Returns the first overflow page number (embedded in the leaf cell). Each overflow page: 4-byte next-page pointer + up to (CBM_PAGE_SIZE-4) bytes of data.
| 854 | // Returns the first overflow page number (embedded in the leaf cell). |
| 855 | // Each overflow page: 4-byte next-page pointer + up to (CBM_PAGE_SIZE-4) bytes of data. |
| 856 | static uint32_t write_overflow_pages(FILE *fp, uint32_t *next_page, const uint8_t *data, |
| 857 | int data_len) { |
| 858 | int per_page = CBM_PAGE_SIZE - BTREE_PTR_SIZE; |
| 859 | uint32_t first_page = 0; |
| 860 | long prev_next_ptr_offset = -SKIP_ONE; |
| 861 | |
| 862 | int offset = 0; |
| 863 | while (offset < data_len) { |
| 864 | uint32_t pnum = (*next_page)++; |
| 865 | if (first_page == 0) { |
| 866 | first_page = pnum; |
| 867 | } |
| 868 | |
| 869 | // Backpatch previous overflow page's next-page pointer |
| 870 | if (prev_next_ptr_offset >= 0) { |
| 871 | uint8_t ptr[BTREE_PTR_SIZE]; |
| 872 | put_u32(ptr, pnum); |
| 873 | (void)fseek(fp, prev_next_ptr_offset, SEEK_SET); |
| 874 | (void)fwrite(ptr, SKIP_ONE, BTREE_PTR_SIZE, fp); |
| 875 | } |
| 876 | |
| 877 | int chunk = data_len - offset; |
| 878 | if (chunk > per_page) { |
| 879 | chunk = per_page; |
| 880 | } |
| 881 | |
| 882 | uint8_t page[CBM_PAGE_SIZE]; |
| 883 | memset(page, 0, CBM_PAGE_SIZE); |
| 884 | put_u32(page, 0); // next-page pointer — 0 for now, backpatched on next iteration |
| 885 | memcpy(page + BTREE_PTR_SIZE, data + offset, chunk); |
| 886 | |
| 887 | long page_offset = (long)(pnum - SKIP_ONE) * CBM_PAGE_SIZE; |
| 888 | prev_next_ptr_offset = page_offset; |
| 889 | (void)fseek(fp, page_offset, SEEK_SET); |
| 890 | (void)fwrite(page, SKIP_ONE, CBM_PAGE_SIZE, fp); |
| 891 | |
| 892 | offset += chunk; |
| 893 | } |
| 894 | return first_page; |
| 895 | } |
| 896 | |
| 897 | // --- Index record builders --- |
| 898 |
no test coverage detected