| 2555 | } |
| 2556 | |
| 2557 | Status BlockBasedTable::Prefetch(const Slice* const begin, |
| 2558 | const Slice* const end) { |
| 2559 | auto& comparator = rep_->internal_comparator; |
| 2560 | auto user_comparator = comparator.user_comparator(); |
| 2561 | // pre-condition |
| 2562 | if (begin && end && comparator.Compare(*begin, *end) > 0) { |
| 2563 | return Status::InvalidArgument(*begin, *end); |
| 2564 | } |
| 2565 | |
| 2566 | IndexBlockIter iiter_on_stack; |
| 2567 | auto iiter = NewIndexIterator(ReadOptions(), false, &iiter_on_stack); |
| 2568 | std::unique_ptr<InternalIteratorBase<BlockHandle>> iiter_unique_ptr; |
| 2569 | if (iiter != &iiter_on_stack) { |
| 2570 | iiter_unique_ptr = |
| 2571 | std::unique_ptr<InternalIteratorBase<BlockHandle>>(iiter); |
| 2572 | } |
| 2573 | |
| 2574 | if (!iiter->status().ok()) { |
| 2575 | // error opening index iterator |
| 2576 | return iiter->status(); |
| 2577 | } |
| 2578 | |
| 2579 | // indicates if we are on the last page that need to be pre-fetched |
| 2580 | bool prefetching_boundary_page = false; |
| 2581 | |
| 2582 | for (begin ? iiter->Seek(*begin) : iiter->SeekToFirst(); iiter->Valid(); |
| 2583 | iiter->Next()) { |
| 2584 | BlockHandle block_handle = iiter->value(); |
| 2585 | const bool is_user_key = |
| 2586 | rep_->found_table_properties && |
| 2587 | rep_->table_properties_base.index_key_is_user_key > 0; |
| 2588 | if (end && |
| 2589 | ((!is_user_key && comparator.Compare(iiter->key(), *end) >= 0) || |
| 2590 | (is_user_key && |
| 2591 | user_comparator->Compare(iiter->key(), ExtractUserKey(*end)) >= 0))) { |
| 2592 | if (prefetching_boundary_page) { |
| 2593 | break; |
| 2594 | } |
| 2595 | |
| 2596 | // The index entry represents the last key in the data block. |
| 2597 | // We should load this page into memory as well, but no more |
| 2598 | prefetching_boundary_page = true; |
| 2599 | } |
| 2600 | |
| 2601 | // Load the block specified by the block_handle into the block cache |
| 2602 | DataBlockIter biter; |
| 2603 | NewDataBlockIterator<DataBlockIter>(rep_, ReadOptions(), block_handle, |
| 2604 | &biter); |
| 2605 | |
| 2606 | if (!biter.status().ok()) { |
| 2607 | // there was an unexpected error while pre-fetching |
| 2608 | return biter.status(); |
| 2609 | } |
| 2610 | } |
| 2611 | |
| 2612 | return Status::OK(); |
| 2613 | } |
| 2614 |
no test coverage detected