| 467 | class HashIndexReader : public IndexReader { |
| 468 | public: |
| 469 | static Status Create( |
| 470 | const SliceTransform* hash_key_extractor, const Footer& footer, |
| 471 | RandomAccessFileReader* file, FilePrefetchBuffer* prefetch_buffer, |
| 472 | const ImmutableCFOptions& ioptions, |
| 473 | const InternalKeyComparator* icomparator, const BlockHandle& index_handle, |
| 474 | InternalIteratorBase<Slice>* meta_index_iter, IndexReader** index_reader, |
| 475 | bool /*hash_index_allow_collision*/, |
| 476 | const PersistentCacheOptions& cache_options, |
| 477 | const bool index_key_includes_seq, const bool index_value_is_full, |
| 478 | MemoryAllocator* memory_allocator) { |
| 479 | std::unique_ptr<Block> index_block; |
| 480 | auto s = ReadBlockFromFile( |
| 481 | file, prefetch_buffer, footer, ReadOptions(), index_handle, |
| 482 | &index_block, ioptions, true /* decompress */, |
| 483 | true /*maybe_compressed*/, Slice() /*compression dict*/, cache_options, |
| 484 | kDisableGlobalSequenceNumber, 0 /* read_amp_bytes_per_bit */, |
| 485 | memory_allocator); |
| 486 | |
| 487 | if (!s.ok()) { |
| 488 | return s; |
| 489 | } |
| 490 | |
| 491 | // Note, failure to create prefix hash index does not need to be a |
| 492 | // hard error. We can still fall back to the original binary search index. |
| 493 | // So, Create will succeed regardless, from this point on. |
| 494 | |
| 495 | auto new_index_reader = new HashIndexReader( |
| 496 | icomparator, std::move(index_block), ioptions.statistics, |
| 497 | index_key_includes_seq, index_value_is_full); |
| 498 | *index_reader = new_index_reader; |
| 499 | |
| 500 | // Get prefixes block |
| 501 | BlockHandle prefixes_handle; |
| 502 | s = FindMetaBlock(meta_index_iter, kHashIndexPrefixesBlock, |
| 503 | &prefixes_handle); |
| 504 | if (!s.ok()) { |
| 505 | // TODO: log error |
| 506 | return Status::OK(); |
| 507 | } |
| 508 | |
| 509 | // Get index metadata block |
| 510 | BlockHandle prefixes_meta_handle; |
| 511 | s = FindMetaBlock(meta_index_iter, kHashIndexPrefixesMetadataBlock, |
| 512 | &prefixes_meta_handle); |
| 513 | if (!s.ok()) { |
| 514 | // TODO: log error |
| 515 | return Status::OK(); |
| 516 | } |
| 517 | |
| 518 | Slice dummy_comp_dict; |
| 519 | // Read contents for the blocks |
| 520 | BlockContents prefixes_contents; |
| 521 | BlockFetcher prefixes_block_fetcher( |
| 522 | file, prefetch_buffer, footer, ReadOptions(), prefixes_handle, |
| 523 | &prefixes_contents, ioptions, true /*decompress*/, |
| 524 | true /*maybe_compressed*/, dummy_comp_dict /*compression dict*/, |
| 525 | cache_options, memory_allocator); |
| 526 | s = prefixes_block_fetcher.ReadBlockContents(); |
nothing calls this directly
no test coverage detected