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
Copy file name to clipboardExpand all lines: open-log/rfcs/0001-storage.md
+28-13Lines changed: 28 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,6 +61,31 @@ This approach simplifies ingestion by avoiding per-key sequence tracking. The tr
61
61
62
62
If SlateDB supports multi-writer in the future, each writer would maintain its own sequence counter. This design assumes each key would still have a single writer—interleaving appends from multiple writers to the same key would break monotonic ordering within that key's log.
63
63
64
+
### SST Representation
65
+
66
+
Open-log proposes two enhancements to SlateDB's SST structure to support efficient `scan` and `count` operations.
67
+
68
+
#### Block Record Counts
69
+
70
+
Each block entry in the SST index would include a cumulative record count:
This enables counting records in a range by scanning the LSM at the index level rather than reading all entries. Block boundaries may not align with the query range, so the first and last blocks in each overlapping level may need to be read for exact counts. An approximate count can be computed from the index alone.
77
+
78
+
#### Bloom Filter Granularity
79
+
80
+
SlateDB SSTs include bloom filters to accelerate point lookups. For open-log, the bloom filter should be keyed on the log key alone, not the composite SlateDB key which includes the sequence number. This allows the bloom filter to indicate whether a given log is present in an SST, reducing the blocks read during `scan` or `count` queries.
81
+
82
+
### Append-Only Scan Optimization
83
+
84
+
In a typical key-value store, range scans must concurrently merge all LSM levels because any level may contain the most recent value for a given key. The append-only structure of open-log provides a stronger guarantee: newer entries are always in higher levels (L0 and recent sorted runs), while older entries settle into deeper levels through compaction.
85
+
86
+
This ordering guarantee enables level-by-level iteration rather than concurrent merging. For queries targeting the tip of a log, we can avoid loading blocks from older levels entirely. This improves performance and prevents cache thrashing from loading historical data that isn't needed.
87
+
88
+
How this optimization can be exposed in SlateDB remains to be explored.
64
89
65
90
### Write API
66
91
@@ -108,19 +133,9 @@ impl OpenLog {
108
133
}
109
134
```
110
135
111
-
### Lag and Count (under consideration)
112
-
113
-
Lag is a critical metric for tracking progress reading from a log. Without contiguous sequence numbers, computing lag requires additional bookkeeping. The approach under consideration augments SlateDB's SST index structure.
114
-
115
-
Each block entry in the SST index would include a cumulative record count:
To count records in a range, we scan the LSM at the index level rather than reading all entries. However, block boundaries may not align with the query range. Within each level of the LSM that overlaps our target range, we may need to read the first and last blocks from that range to determine the exact offset relative to block boundaries.
136
+
### Count API (under consideration)
122
137
123
-
An approximate count could be offered based on the index alone without reading any blocks—useful when exact counts are not required.
138
+
Lag is a critical metric for tracking progress reading from a log. Without contiguous sequence numbers, computing lag requires the SST enhancements described in [SST Representation](#sst-representation).
124
139
125
140
```rust
126
141
// TODO: decide which SlateDB ScanOptions parameters to pass through
@@ -133,7 +148,7 @@ impl OpenLog {
133
148
}
134
149
```
135
150
136
-
This mirrors the scan API but returns a count rather than entries.
151
+
This mirrors the scan API but returns a count rather than entries. The `approximate` option allows counting from the index alone without reading boundary blocks.
0 commit comments