···250250251251### Subtables
252252253253-Each sub consists of key/value pairs in sorted order followed by their indexes and then a trailer indicating the number of pairs.
253253+A subtable ("sub") is a subset of a table which contains a range of key/value pairs.
254254+Subs are limited to 64 KiB in size, but could be smaller due to compression
255255+(compression is future work).
254256255255-Subs target a particular max size (64 KiB) but are intentionally variable in length to allow for efficient compression
256256-(compression is future work and not specified in this document).
257257+The key/value pairs are written contiguously in the following format:
257258258259```
259259-# Key/value pair:
260260+# Key/Value Pair
260261key (variable) | version (8 bytes) | type (1 byte) | value (variable)
261261-262262-# Key index:
263263-offset (3 bytes) | key length (2 bytes)
264264-265265-# Trailer
266266-pair_count (2 bytes)
267262```
268263269264The `key` and `value` are self-explanatory.
270270-271271-The `version` is the 8-byte database version (we may be able to compress these in the future).
272272-273273-The `type` is either `0` for an insert or `1` for a tombstone.
274274-Note that for a tombstone the value would naturally be 0 bytes in length.
275275-276276-The `offset`s and `length`s of the keys are written consecutively after the pair data.
277277-Note that the lengths of the values are stored implicitly as a value takes up all remaining space between `offset`s.
278278-279279-The `pair_count` tells us how many offsets/lengths to expect.
265265+The `version` is the database version of the key.
280266281281-The algorithm to perform a lookup within a sub is as follows:
267267+The `type` is `0` for an insert or `1` for a tombstone.
268268+Note that for a tombstone the value would naturally be zero bytes in length.
282269283283-1. Read the sub into memory in full as a single binary term.
270270+Because keys and values are variable in length,
271271+the pairs are followed by an array of fixed-length slots:
284272285285-2. Read the last byte to determine the `pair_count`.
273273+```
274274+# Pair Slot
275275+offset (3 bytes) | key length (2 bytes)
276276+```
286277287287-3. Read the offsets/lengths from the range `[byte_length(sub) - ((pair_count * 5) - 2), byte_length(sub) - 2)`.
288288- This results in a list `[{offset, key_length}, ...]` with an entry for each pair in the sub.
278278+Finally, the slot array is followed by a fixed-length sub trailer:
289279290290- We could also compute the `value_length` here by looking at the next `offset` for each pair.
280280+```
281281+# Subtable Trailer
282282+pair_count (2 bytes)
283283+```
291284292292-4. Binary search the pairs.
293293- Using the offsets, we can look up any pair's key at the byte range `[index, index + key_length + 8)`.
294294- Note that we *include* the version (8 bytes) in the key when binary searching because this is a multiversion LSM.
285285+The `pair_count` records the number of pairs in the subtable,
286286+which is needed to binary search the slot array.