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.
| 1082 | // overflow pages: varint(payload_len) + payload[0..local) + u32(first_ovfl). |
| 1083 | // Returns the (possibly new, malloc'd) cell; frees the original when replaced. |
| 1084 | static uint8_t *overflowize_index_cell(FILE *fp, uint32_t *next_page, uint8_t *cell, |
| 1085 | int *cell_len) { |
| 1086 | uint64_t plen = 0; |
| 1087 | int vlen = get_varint(cell, &plen); |
| 1088 | if ((int64_t)plen <= INDEX_OVERFLOW_MAX_LOCAL) { |
| 1089 | return cell; |
| 1090 | } |
| 1091 | int64_t per_ovfl = (int64_t)CBM_PAGE_SIZE - BTREE_PTR_SIZE; |
| 1092 | int64_t k = INDEX_OVERFLOW_MIN_LOCAL + (((int64_t)plen - INDEX_OVERFLOW_MIN_LOCAL) % per_ovfl); |
| 1093 | int local = (k <= INDEX_OVERFLOW_MAX_LOCAL) ? (int)k : INDEX_OVERFLOW_MIN_LOCAL; |
| 1094 | uint32_t first_ovfl = |
| 1095 | write_overflow_pages(fp, next_page, cell + vlen + local, (int)plen - local); |
| 1096 | int nlen = vlen + local + BTREE_PTR_SIZE; |
| 1097 | uint8_t *data = (uint8_t *)malloc((size_t)nlen); |
| 1098 | if (!data) { |
| 1099 | return cell; /* fall back to the (broken) inline form on OOM */ |
| 1100 | } |
| 1101 | memcpy(data, cell, (size_t)(vlen + local)); |
| 1102 | put_u32(data + vlen + local, first_ovfl); |
| 1103 | free(cell); |
| 1104 | *cell_len = nlen; |
| 1105 | return data; |
| 1106 | } |
| 1107 | #define TABLE_OVERFLOW_MIN_LOCAL 8199 |
| 1108 | |
| 1109 | // Add a table cell to the PageBuilder, flushing leaf pages as needed. |
no test coverage detected