The TransactionHistoryIterator is a merge iterator designed to provide RYOW (Read Your Own Writes) semantics within a transaction. It achieves this by merging two distinct data sources:
- Snapshot: Committed data stored in the LSM tree, containing all historical versions.
- Write-set: Uncommitted writes belonging to the current transaction (pending changes).
By overlaying the write-set on top of the snapshot, the iterator ensures that a transaction can see its own uncommitted writes as if they were already committed. When a key and timestamp exist in both sources, the write-set entry takes precedence.
Data Model
Each entry in the merged stream consists of (key, timestamp, value):
- Key: The user-provided key.
- Timestamp: The version number (higher values indicate newer versions).
- Value: The data associated with the key, or a tombstone marker for soft deletes.
Ordering Logic
Iteration order depends on the direction:
- Forward iteration (
seek_first, next):- Primary:
key ASC (e.g., a < b < c) - Secondary:
timestamp DESC (newer versions appear before older ones)
- Backward iteration (
seek_last, prev):- Primary:
key DESC (e.g., c > b > a) - Secondary:
timestamp ASC (older versions appear before newer ones)
Snapshot (committed): Write-set (transaction):
┌─────────┬────┬───────┐ ┌─────────┬────┬───────┐
│ Key │ TS │ Value │ │ Key │ TS │ Value │
├─────────┼────┼───────┤ ├─────────┼────┼───────┤
│ "a" │ 50 │ "v1" │ │ "b" │ 80 │ "v4" │
│ "a" │ 30 │ "v0" │ └─────────┴────┴───────┘
│ "c" │ 40 │ "v2" │
└─────────┴────┴───────┘
Forward iteration produces:
("a",50) ← snap wins, "a" < "b"
("a",30) ← snap wins, "a" < "b"
("b",80) ← write-set wins, "b" < "c"
("c",40) ← snap (write-set exhausted)