Rest of the index page is filled with index values.
Index value translates Record ID (recid) into offset in file and record size. Position and size of record might change as data are updated, that makes index tables necessary. Index Value is 8 byte long with parity 1
val>>48
to get itval&MOFFSET
to get itlinked && size==0
indicates null record. Use val&MLINKED
.val&MUNUSED
val&MARCHIVE
Maximal record size is 64KB (16bits). To store larger records StoreDirect links multiple records into single one. Linked records starts with Index Value where Linked Record is indicates by a bit. If this bit is not set, entire record is reserved for record data. If Linked bit is set, than first 8 bytes store Record Link with offset and size of the next part.
Structure of Record Link is similar to Index Value. Except parity is 3.
val>>48
to get itval&MOFFSET
to get itbite 4 - true if next record is linked, false if next record is last and not linked (is tail of linked record).
Use val&MLINKED
Tail of linked record (last part) does not have 8-byte Record Link at beginning.
Long Stack is linked queue of longs stored as part of storage. It supports two operations: put and take, longs are returned in FIFO order. StoreDirect uses this structure to keep track of free space. Space allocation involves taking long from stack. There are more stacks, each size has its own stack, there is also stack to keep track of free recids. For space usage there are in total 64K / 16 = 4096
Long Stacks (maximal non-linked record size is 64K and records are aligned to 16 bytes).
Long stack is organized similar way as linked record. It is stored in chunks, each chunks contains multiple long values and link to next chunk. Chunks size varies. Long values are stored in bidirectional-packed form, to make unpacking possible in both directions. Single value occupies from 2 bytes to 9 bytes. TODO explain bidi-packing, for now see DataIO class.
Each Long Stack is identified by master pointer, which points to its last chunk. Master Pointer for each Long Stack is stored in head of storage file at its reserved offset (zero page). Head chunk is not linked directly, one has to fully traverse Long Stack to get to head.
Structure of Long Stack Chunk is as follow:
Master Link structure:
Adding value to Long Stack goes as follow:
Taking value:
WAL protects storage from data corruption if transactions are enabled. Technically it is sequence of instructions written to append-only file. Each instruction says something like: ‘write this data at this offset’. TODO explain WAL.
WAL is stored in sequence of files.
Each instruction starts with single byte header. First 3 bits indicate type of instruction. Last 5 bits contain checksum to verify instruction.
Type of instructions:
bit parity from offset & 31
(bit count from 15 bytes + 1)&31
(bit count from size + bit count from offset + 1 )&31
(bit count from 3 bytes + 1)&31
bit count from offset & 31
bit count from offset & 31
bit count from offset & 31
SortedTableMap
uses its own file format. File is split into page, where page size is power of two and maximal page size 1MB.
Each page has header. Header size is bigger for zero page, because it also contains file header. TODO header size.
After header there is a series of 4-byte integers.
First integer is number of nodes on this page (N). It is followed by N*2 integers. First N integers are offsets of key arrays for each node. Next N integers are offsets for value arrays for each node. Offsets are relative to page offset. The last integer points to end of data, rest of the page after that offset is filled with zeroes.
Offsets of key array (number i) are stored at: PAGE_OFFSET + HEAD_SIZE + I*4
.
Offsets of value array (number i) are stored at: PAGE_OFFSET + HEAD_SIZE + (NODE_COUNT + I) * 4
.