If an index cell's payload exceeds X, rewrite it to spill the tail to overflow pages: varint(payload_len) + payload[0..local) + u32(first_ovfl). Returns the (possibly new, malloc'd) cell; frees the original when replaced.
| 1103 | // overflow pages: varint(payload_len) + payload[0..local) + u32(first_ovfl). |
| 1104 | // Returns the (possibly new, malloc'd) cell; frees the original when replaced. |
| 1105 | static uint8_t *overflowize_index_cell(FILE *fp, uint32_t *next_page, uint8_t *cell, |
| 1106 | int *cell_len) { |
| 1107 | uint64_t plen = 0; |
| 1108 | int vlen = get_varint(cell, &plen); |
| 1109 | if ((int64_t)plen <= INDEX_OVERFLOW_MAX_LOCAL) { |
| 1110 | return cell; |
| 1111 | } |
| 1112 | int64_t per_ovfl = (int64_t)CBM_PAGE_SIZE - BTREE_PTR_SIZE; |
| 1113 | int64_t k = INDEX_OVERFLOW_MIN_LOCAL + (((int64_t)plen - INDEX_OVERFLOW_MIN_LOCAL) % per_ovfl); |
| 1114 | int local = (k <= INDEX_OVERFLOW_MAX_LOCAL) ? (int)k : INDEX_OVERFLOW_MIN_LOCAL; |
| 1115 | uint32_t first_ovfl = |
| 1116 | write_overflow_pages(fp, next_page, cell + vlen + local, (int)plen - local); |
| 1117 | int nlen = vlen + local + BTREE_PTR_SIZE; |
| 1118 | uint8_t *data = (uint8_t *)malloc((size_t)nlen); |
| 1119 | if (!data) { |
| 1120 | return cell; /* fall back to the (broken) inline form on OOM */ |
| 1121 | } |
| 1122 | memcpy(data, cell, (size_t)(vlen + local)); |
| 1123 | put_u32(data + vlen + local, first_ovfl); |
| 1124 | free(cell); |
| 1125 | *cell_len = nlen; |
| 1126 | return data; |
| 1127 | } |
| 1128 | #define TABLE_OVERFLOW_MIN_LOCAL 8199 |
| 1129 | |
| 1130 | // Add a table cell to the PageBuilder, flushing leaf pages as needed. |
no test coverage detected