You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Background memtable flush → immutable columnar raw segments, partitioned by `bucket = blake3(account_id) % bucket_count`
120
+
- Background memtable flush → immutable columnar raw segments, partitioned by `bucket = blake3(account_id) % bucket_count`, written in canonical billing order `(account, product, meter, model, ts)` (sort-on-flush) so compaction is cheaper and dictionary encoding compresses better
121
+
- Exclusive process lock (`db_root/LOCK` via `flock`) — prevents server + admin commands from racing on the same database
121
122
- Columnar on-disk format with per-column zstd compression and blake3 checksum (see [Segment format](#segment-format))
122
123
- Background hourly rollup scheduler — seals completed hours into per-bucket rollup segments, advances the manifest watermark atomically, query path routes `RollupHourly` through rollups with raw fallback for the open-period tail
123
124
- Background compaction scheduler — merges small per-bucket segments into a single output, applies the `ReplacementRecord` to the manifest, deletes old files after a configurable reader grace period (spec §15.3)
@@ -144,7 +145,6 @@ db_root/
144
145
145
146
Known gaps (tracked against `rust_ai_usage_db_spec.md`):
146
147
147
-
- No RLE encoding yet (used for `kind`-style low-cardinality columns); `Plain` + zstd handles it adequately.
148
148
- No block-level metadata for fine-grained skipping inside a segment; pruning is segment-level only.
149
149
- Rollup segments still use length-prefixed bincode (not the columnar format) — they're tiny so it hasn't been a win yet
150
150
- COUNT semantics differ for `RollupHourly` queries: each rollup row counts as 1, not as the number of underlying events. Use `RawEvents` source for exact event counts.
@@ -178,10 +178,11 @@ Each column payload before compression is encoded based on its declared `encodin
|`Rle` (4) | bincode `Vec<(u8, u32)>` of (value, run_length) |`kind`|
185
186
186
187
Dictionary collapses ID columns from O(rows × string size) to O(unique values × string size + 4 bytes/row); for ID-heavy workloads this is a 1000× shrink on the column. Delta encoding turns near-monotonic timestamps into small differences that zstd compresses dramatically better. Zigzag-varint packs small i128 quantities into 1–2 bytes instead of 16.
0 commit comments