@@ -85,7 +85,7 @@ static bool InheritanceMismatch(const FileMetaData& sst_meta,
8585 return true ;
8686}
8787
88- // Store params for create depend table iterator in future
88+ // Store params for create dependency table iterator in future
8989class LazyCreateIterator : public Snapshot {
9090 TableCache* table_cache_;
9191 ReadOptions options_; // deep copy
@@ -292,7 +292,7 @@ InternalIterator* TableCache::NewIterator(
292292 }
293293 size_t readahead = 0 ;
294294 bool record_stats = !for_compaction;
295- if (file_meta.prop .is_map_sst ()) {
295+ if (file_meta.prop .is_map_sst () || file_meta. prop . is_link_sst () ) {
296296 record_stats = false ;
297297 } else {
298298 // MapSST don't handle these
@@ -340,22 +340,17 @@ InternalIterator* TableCache::NewIterator(
340340 }
341341 InternalIterator* result = nullptr ;
342342 if (s.ok ()) {
343- if (!file_meta.prop .is_map_sst ()) {
344- if (options.table_filter &&
345- !options.table_filter (*table_reader->GetTableProperties ())) {
346- result = NewEmptyInternalIterator<LazyBuffer>(arena);
347- } else {
348- result = table_reader->NewIterator (options, prefix_extractor, arena,
349- skip_filters, for_compaction);
350- }
351- } else {
343+ // For map & linked SST, we should expand their underlying key value pairs,
344+ // not simply iterate the input SST key values.
345+ if (file_meta.prop .is_map_sst () || file_meta.prop .is_link_sst ()) {
352346 ReadOptions map_options = options;
353347 map_options.total_order_seek = true ;
354348 map_options.readahead_size = 0 ;
355349 result =
356350 table_reader->NewIterator (map_options, prefix_extractor, arena,
357351 skip_filters, false /* for_compaction */ );
358352 if (!dependence_map.empty ()) {
353+ // Map SST will handle range deletion internally, so we can skip here.
359354 bool ignore_range_deletions =
360355 options.ignore_range_deletions ||
361356 file_meta.prop .map_handle_range_deletions ();
@@ -365,33 +360,54 @@ InternalIterator* TableCache::NewIterator(
365360 lazy_create_iter = new (buffer) LazyCreateIterator (
366361 this , options, env_options, range_del_agg, prefix_extractor,
367362 for_compaction, skip_filters, ignore_range_deletions, level);
368-
369363 } else {
370364 lazy_create_iter = new LazyCreateIterator (
371365 this , options, env_options, range_del_agg, prefix_extractor,
372366 for_compaction, skip_filters, ignore_range_deletions, level);
373367 }
374- auto map_sst_iter = NewMapSstIterator (
375- &file_meta, result, dependence_map, ioptions_.internal_comparator ,
376- lazy_create_iter, c_style_callback (*lazy_create_iter), arena);
368+
369+ // For map & linked sst, we should expand their dependencies and merge
370+ // all related iterators into one combined iterator for further reads.
371+ InternalIterator* sst_iter = nullptr ;
372+
373+ if (file_meta.prop .is_map_sst ()) {
374+ sst_iter = NewMapSstIterator (
375+ &file_meta, result, dependence_map, ioptions_.internal_comparator ,
376+ lazy_create_iter, c_style_callback (*lazy_create_iter), arena);
377+ } else {
378+ assert (file_meta.prop .is_link_sst ());
379+ sst_iter = NewLinkSstIterator (
380+ &file_meta, result, dependence_map, ioptions_.internal_comparator ,
381+ lazy_create_iter, c_style_callback (*lazy_create_iter), arena);
382+ }
383+
377384 if (arena != nullptr ) {
378- map_sst_iter ->RegisterCleanup (
385+ sst_iter ->RegisterCleanup (
379386 [](void * arg1, void * arg2) {
380387 static_cast <InternalIterator*>(arg1)->~InternalIterator ();
381388 static_cast <LazyCreateIterator*>(arg2)->~LazyCreateIterator ();
382389 },
383390 result, lazy_create_iter);
384391 } else {
385- map_sst_iter ->RegisterCleanup (
392+ sst_iter ->RegisterCleanup (
386393 [](void * arg1, void * arg2) {
387394 delete static_cast <InternalIterator*>(arg1);
388395 delete static_cast <LazyCreateIterator*>(arg2);
389396 },
390397 result, lazy_create_iter);
391398 }
392- result = map_sst_iter;
399+ result = sst_iter;
400+ }
401+ } else {
402+ if (options.table_filter &&
403+ !options.table_filter (*table_reader->GetTableProperties ())) {
404+ result = NewEmptyInternalIterator<LazyBuffer>(arena);
405+ } else {
406+ result = table_reader->NewIterator (options, prefix_extractor, arena,
407+ skip_filters, for_compaction);
393408 }
394409 }
410+
395411 if (create_new_table_reader) {
396412 assert (handle == nullptr );
397413 result->RegisterCleanup (&DeleteTableReader, table_reader,
0 commit comments