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
sstable: lazy load the index block in single level iterator
This commit implements the index block lazy loading in single-level iterator as default behavior.
The index block loading is now deferred until first access. At the same time, it leads to semantic
changes as the file reading ordering changes because of this.
Here is a quick overview of the change.
Before (eager loading)
1. Iterator Construction:
1.1 the constructor calls readTopLevelIndexBlock()
1.2 readTopLevelIndexBlock() calls readIndexBlock()
1.3 readIndexBlock(() calls blockReader.Read()
1.4 blockReader.Read() calls objstorage ReadHandle ReadAt()
1.5 ReadAt() loads the index block
1.6 construction completes
2. First Positioning (e.g., First(), SeekGE(), SeekPrefixGE()):
2.1 the positioning function uses the already-loaded index via PI(&i.index)
2.2 file opened for data read
2.3 ReadAt() loads the data block
After (lazy loading)
1. Iterator Construction:
1.1 the constructor sets indexLoaded = false to defer loading
1.2 construction completes (no I/O)
2. First Positioning (e.g., First(), SeekGE(), SeekPrefixGE()):
2.1 the positioning function calls the new indexIter() wrapper
2.2 indexIter() calls ensureIndexLoaded()
2.3 ensureIndexLoaded() calls ReadAt()
2.4 ReadAt() loads the index block
2.5 uses the newly-loaded index for positioning
2.6 ReadAt() loads the data block
As seen above, the I/O operation is now deferred. While the overall behavior is transparent to
users, the internal semantic is different now. And the data-driven tests have to change
accordingly. See the order of events change in file: checkpoint, cleaner, and event_listener.
What's interesting (optimized) is the change observed in flushable_ingest, which demonstrate
the I/O saving thanks to the optimization.
```
-# When the key doesn't pass the bloom filter, we should see only two block
-# reads.
+# When the key doesn't pass the bloom filter, we should see only one block
+# read due to lazy loading optimization - bloom filter is checked first,
+# and if it rejects the key, we can avoid loading the index block entirely.
get with-fs-logging
small-00001-does-not-exist
----
-read-at(158, 41): 000004.sst
read-at(199, 74): 000004.sst
```
implements #3248
0 commit comments