···163163164164## Tables
165165166166-Tables are the on-disk "files" which store multiversion key/value pairs.
167167-In many LSM trees they are actual files, but here we use a single file and allocate blocks within that file ourselves.
166166+A table is a collection of multiversion key/value pairs stored in lexicographic order.
167167+Tables are large (32 MiB) and pairs are written compactly with no slack space or padding.
168168+169169+A table consists of a number of subtables (or "subs") which are written consecutively to disk.
170170+The subs are followed first by a table index, which records the byte offset and key bounds of each sub,
171171+and then by a table trailer which records the metadata needed to read the table.
172172+173173+At a high level, a lookup against the table can be performed as follows:
174174+175175+1. Read the last block of the table and load the table's metadata.
176176+2. Binary search the table index to find the location of the sub containing the desired key.
177177+3. Binary search the sub to find the key and its value.
178178+179179+### Table trailer
180180+181181+The trailer is fully contained by the last block of the table and is aligned to the end of that block.
182182+183183+The trailer consists of:
184184+185185+- A list of block addresses (`index` and `checksum`) for the blocks in the table
186186+- The fixed-length metadata needed to decode the table
187187+188188+#### Metadata
189189+190190+The metadata is fixed-length and consists of the last 12 bytes of the last block of the table.
191191+192192+```
193193+# Metadata:
194194+block_count (4 bytes) | index_slots_offset (4 bytes) | subtable_count (4 bytes)
195195+```
196196+197197+The `block_count` records the number of block address entries which directly precede the metadata.
198198+Block address entries are fixed-length, so the count is enough to decode the addresses.
199199+200200+The `index_slots_offset` records the byte offset of the table index's fixed-length slots.
201201+The `subtable_count` records the number of subtables in the table.
202202+Together, these can be used to locate the table index's slots and then binary search the index to find a sub.
203203+204204+#### Block addresses
205205+206206+The block addresses constitute a lookup table which can be used to find the block for a given byte offset in the table.
207207+There is no guarantee that these addresses are consecutive, as allocation will fragment over time.
168208169169-Tables are large (32 MiB) and store keys (with versions) in sorted order.
170170-The LSM is leveled, so within each level a table stores a disjoint portion of the keyspace.
209209+Each block address entry consists of 24 bytes:
171210172172-Each table is organized into subtables ("subs").
173173-Subs are written sequentially, and then an index with the `start_key` for each sub is written to the end of the table.
174174-Along with the manifest, this forms a tree structure: manifest -> table index -> subtable -> key/value pair.
211211+```
212212+# Block address entry:
213213+index (8 bytes) | checksum (16 bytes)
214214+```
175215176176-Tables are written by a merge process, which accumulates pairs in sorted order and writes them out one sub at a time.
216216+By storing the list of block addresses entirely within the last block,
217217+we avoid having to build a linked list of blocks for the trailer.
218218+We can fit roughly 20,000 24-byte addresses within a 512 KiB block,
219219+so this approach limits us to a table size of around 10 GiB: *far* larger than we will ever need.
177220178221### Subtables
179222···246289The length of the `key` is stored implicitly as the difference between slot `offset`s.
247290248291The sub entries can be binary searched with an algorithm similar to that of the subs detailed above.
249249-250250-### Table Trailer
251251-252252-At the end of the last block of the table, a metadata trailer is written.
253253-The table trailer consists of a list of addresses for the blocks of the table and then the top-level metadata values.
254254-If there is not enough room for this trailer in the last block, a new last block is allocated.
255255-256256-```
257257-# Block entry:
258258-block_offset (8 bytes) | block_checksum (16 bytes)
259259-260260-# Metadata:
261261-block_count (2 bytes) | sub_count (4 bytes) | index_offset (4 bytes) | index_size (4 bytes)
262262-```
263263-264264-Each block entry consists of a block address as defined previously (`block_offset` and `block_checksum`).
265265-266266-The `block_count` holds the number block entries (addresses).
267267-268268-The `sub_count` is the number of subs, and the `index_offset` and `index_size` are the offset/size of the table index.