| 490 | // Note that changing the following value constitutes a change in index numbering. |
| 491 | #define KV_FRAGMENT_INDEX_SIZE_HINT_FACTOR 4 |
| 492 | Value encodeKVFragment(KeyValueRef kv, uint32_t index) { |
| 493 | int keyCode = kv.key.size() * 2 + 12; |
| 494 | int valCode = kv.value.size() * 2 + 12; |
| 495 | // The SQLite type code for the index is the minimal number of bytes needed to store |
| 496 | // a signed representation of the index value. The type code for 0 is 0 (which is |
| 497 | // actually the null type in SQLite). |
| 498 | int8_t indexCode = 0; |
| 499 | if (index != 0) { |
| 500 | uint32_t tmp = index; |
| 501 | while (tmp != 0) { |
| 502 | ++indexCode; |
| 503 | tmp >>= 8; |
| 504 | } |
| 505 | // An increment is required if the high bit of the N-byte index value is set, since it is |
| 506 | // positive number but SQLite only stores signed values and would interpret it as negative. |
| 507 | if (index >> (8 * indexCode - 1)) |
| 508 | ++indexCode; |
| 509 | } |
| 510 | |
| 511 | int header_size = sqlite3VarintLen(keyCode) + sizeof(indexCode) + sqlite3VarintLen(valCode); |
| 512 | int hh = sqlite3VarintLen(header_size); |
| 513 | header_size += hh; |
| 514 | if (hh < sqlite3VarintLen(header_size)) |
| 515 | header_size++; |
| 516 | int size = header_size + kv.key.size() + indexCode + kv.value.size(); |
| 517 | |
| 518 | Value v; |
| 519 | uint8_t* d = new (v.arena()) uint8_t[size]; |
| 520 | ((ValueRef&)v) = KeyRef(d, size); |
| 521 | d += sqlite3PutVarint(d, header_size); |
| 522 | d += sqlite3PutVarint(d, keyCode); |
| 523 | *d++ = indexCode; |
| 524 | d += sqlite3PutVarint(d, valCode); |
| 525 | |
| 526 | // Write key |
| 527 | memcpy(d, kv.key.begin(), kv.key.size()); |
| 528 | d += kv.key.size(); |
| 529 | |
| 530 | // Write index bytes, if any |
| 531 | for (int i = indexCode - 1; i >= 0; --i) { |
| 532 | d[i] = (uint8_t)index; |
| 533 | index >>= 8; |
| 534 | } |
| 535 | d += indexCode; |
| 536 | |
| 537 | // Write value |
| 538 | memcpy(d, kv.value.begin(), kv.value.size()); |
| 539 | d += kv.value.size(); |
| 540 | ASSERT(d == v.begin() + size); |
| 541 | return v; |
| 542 | } |
| 543 | |
| 544 | int getEncodedSize(int keySize, int valuePrefixSize) { |
| 545 | int keyCode = keySize * 2 + 12; |
no test coverage detected