xref: /aosp_15_r20/external/leveldb/doc/log_format.md (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
1*9507f98cSAndroid Build Coastguard Workerleveldb Log format
2*9507f98cSAndroid Build Coastguard Worker==================
3*9507f98cSAndroid Build Coastguard WorkerThe log file contents are a sequence of 32KB blocks.  The only exception is that
4*9507f98cSAndroid Build Coastguard Workerthe tail of the file may contain a partial block.
5*9507f98cSAndroid Build Coastguard Worker
6*9507f98cSAndroid Build Coastguard WorkerEach block consists of a sequence of records:
7*9507f98cSAndroid Build Coastguard Worker
8*9507f98cSAndroid Build Coastguard Worker    block := record* trailer?
9*9507f98cSAndroid Build Coastguard Worker    record :=
10*9507f98cSAndroid Build Coastguard Worker      checksum: uint32     // crc32c of type and data[] ; little-endian
11*9507f98cSAndroid Build Coastguard Worker      length: uint16       // little-endian
12*9507f98cSAndroid Build Coastguard Worker      type: uint8          // One of FULL, FIRST, MIDDLE, LAST
13*9507f98cSAndroid Build Coastguard Worker      data: uint8[length]
14*9507f98cSAndroid Build Coastguard Worker
15*9507f98cSAndroid Build Coastguard WorkerA record never starts within the last six bytes of a block (since it won't fit).
16*9507f98cSAndroid Build Coastguard WorkerAny leftover bytes here form the trailer, which must consist entirely of zero
17*9507f98cSAndroid Build Coastguard Workerbytes and must be skipped by readers.
18*9507f98cSAndroid Build Coastguard Worker
19*9507f98cSAndroid Build Coastguard WorkerAside: if exactly seven bytes are left in the current block, and a new non-zero
20*9507f98cSAndroid Build Coastguard Workerlength record is added, the writer must emit a FIRST record (which contains zero
21*9507f98cSAndroid Build Coastguard Workerbytes of user data) to fill up the trailing seven bytes of the block and then
22*9507f98cSAndroid Build Coastguard Workeremit all of the user data in subsequent blocks.
23*9507f98cSAndroid Build Coastguard Worker
24*9507f98cSAndroid Build Coastguard WorkerMore types may be added in the future.  Some Readers may skip record types they
25*9507f98cSAndroid Build Coastguard Workerdo not understand, others may report that some data was skipped.
26*9507f98cSAndroid Build Coastguard Worker
27*9507f98cSAndroid Build Coastguard Worker    FULL == 1
28*9507f98cSAndroid Build Coastguard Worker    FIRST == 2
29*9507f98cSAndroid Build Coastguard Worker    MIDDLE == 3
30*9507f98cSAndroid Build Coastguard Worker    LAST == 4
31*9507f98cSAndroid Build Coastguard Worker
32*9507f98cSAndroid Build Coastguard WorkerThe FULL record contains the contents of an entire user record.
33*9507f98cSAndroid Build Coastguard Worker
34*9507f98cSAndroid Build Coastguard WorkerFIRST, MIDDLE, LAST are types used for user records that have been split into
35*9507f98cSAndroid Build Coastguard Workermultiple fragments (typically because of block boundaries).  FIRST is the type
36*9507f98cSAndroid Build Coastguard Workerof the first fragment of a user record, LAST is the type of the last fragment of
37*9507f98cSAndroid Build Coastguard Workera user record, and MIDDLE is the type of all interior fragments of a user
38*9507f98cSAndroid Build Coastguard Workerrecord.
39*9507f98cSAndroid Build Coastguard Worker
40*9507f98cSAndroid Build Coastguard WorkerExample: consider a sequence of user records:
41*9507f98cSAndroid Build Coastguard Worker
42*9507f98cSAndroid Build Coastguard Worker    A: length 1000
43*9507f98cSAndroid Build Coastguard Worker    B: length 97270
44*9507f98cSAndroid Build Coastguard Worker    C: length 8000
45*9507f98cSAndroid Build Coastguard Worker
46*9507f98cSAndroid Build Coastguard Worker**A** will be stored as a FULL record in the first block.
47*9507f98cSAndroid Build Coastguard Worker
48*9507f98cSAndroid Build Coastguard Worker**B** will be split into three fragments: first fragment occupies the rest of
49*9507f98cSAndroid Build Coastguard Workerthe first block, second fragment occupies the entirety of the second block, and
50*9507f98cSAndroid Build Coastguard Workerthe third fragment occupies a prefix of the third block.  This will leave six
51*9507f98cSAndroid Build Coastguard Workerbytes free in the third block, which will be left empty as the trailer.
52*9507f98cSAndroid Build Coastguard Worker
53*9507f98cSAndroid Build Coastguard Worker**C** will be stored as a FULL record in the fourth block.
54*9507f98cSAndroid Build Coastguard Worker
55*9507f98cSAndroid Build Coastguard Worker----
56*9507f98cSAndroid Build Coastguard Worker
57*9507f98cSAndroid Build Coastguard Worker## Some benefits over the recordio format:
58*9507f98cSAndroid Build Coastguard Worker
59*9507f98cSAndroid Build Coastguard Worker1. We do not need any heuristics for resyncing - just go to next block boundary
60*9507f98cSAndroid Build Coastguard Worker   and scan.  If there is a corruption, skip to the next block.  As a
61*9507f98cSAndroid Build Coastguard Worker   side-benefit, we do not get confused when part of the contents of one log
62*9507f98cSAndroid Build Coastguard Worker   file are embedded as a record inside another log file.
63*9507f98cSAndroid Build Coastguard Worker
64*9507f98cSAndroid Build Coastguard Worker2. Splitting at approximate boundaries (e.g., for mapreduce) is simple: find the
65*9507f98cSAndroid Build Coastguard Worker   next block boundary and skip records until we hit a FULL or FIRST record.
66*9507f98cSAndroid Build Coastguard Worker
67*9507f98cSAndroid Build Coastguard Worker3. We do not need extra buffering for large records.
68*9507f98cSAndroid Build Coastguard Worker
69*9507f98cSAndroid Build Coastguard Worker## Some downsides compared to recordio format:
70*9507f98cSAndroid Build Coastguard Worker
71*9507f98cSAndroid Build Coastguard Worker1. No packing of tiny records.  This could be fixed by adding a new record type,
72*9507f98cSAndroid Build Coastguard Worker   so it is a shortcoming of the current implementation, not necessarily the
73*9507f98cSAndroid Build Coastguard Worker   format.
74*9507f98cSAndroid Build Coastguard Worker
75*9507f98cSAndroid Build Coastguard Worker2. No compression.  Again, this could be fixed by adding new record types.
76