MCPcopy Create free account
hub / github.com/facebook/CacheLib / onKeyHashRetrievalFromLocation

Method onKeyHashRetrievalFromLocation

cachelib/navy/block_cache/BlockCache.cpp:801–897  ·  view source on GitHub ↗

To retrieve the 64bit key hash from the given address. This function will not (and cannot) check if index changed in between this function call for whatever reasons. It's caller's responsibility to make sure the index is not changed and no race condition happens.

Source from the content-addressed store, hash-verified

799// the index is not changed and no race condition happens.
800//
801std::optional<uint64_t> BlockCache::onKeyHashRetrievalFromLocation(
802 uint32_t address) {
803 auto addrEnd = decodeRelAddress(address);
804 // It won't care about seq number here (giving it as std::nullopt). It's
805 // caller's responsibility to check about the race condition for the index
806 // change.
807 auto desc = regionManager_.openForRead(addrEnd.rid(), std::nullopt);
808
809 if (desc.status() != OpenStatus::Ready) {
810 // In rare cases, Region can return 'Retry' when it's being released after
811 // the reclaim. Checking the index again will resolve it since index should
812 // have been updated with the new location
813 return std::nullopt;
814 }
815
816 EntryDesc entryDesc{};
817 uint8_t* entryEnd{nullptr};
818 {
819 SCOPE_EXIT { regionManager_.close(std::move(desc)); };
820 // We only need to read EntryDesc + key. (Key is just for integrity check).
821 // Since we don't know the key size before reading EntryDesc, let's just
822 // read enough buffer to cover most keys. If it's not enough, we can read
823 // more for the key, but that'll be rare cases.
824 auto readSize = std::min(512u, addrEnd.offset());
825
826 auto buffer = regionManager_.read(desc, addrEnd.sub(readSize), readSize);
827 if (buffer.isNull()) {
828 return std::nullopt;
829 }
830
831 entryEnd = buffer.data() + buffer.size();
832 entryDesc = *reinterpret_cast<EntryDesc*>(entryEnd - sizeof(EntryDesc));
833 // check if we have enough buffer read to cover the key
834 if (buffer.size() < sizeof(EntryDesc) + entryDesc.keySize) {
835 // re-read to cover the key. This should be just for the larger keys
836 readSize = sizeof(EntryDesc) + entryDesc.keySize;
837 if (readSize > addrEnd.offset()) {
838 // something's wrong with the key size. It's not within the region
839 // boundary
840 XLOGF(
841 ERR,
842 "Key size {} in item header is crossing the region boundary in "
843 "onKeyHashRetrievalFromLocation(). Region {} is likely corrupted. "
844 "Offset-end: {}, Physical-offset-end: {}, Header size: {}, Header "
845 "(hex): {}",
846 entryDesc.keySize, addrEnd.rid().index(), addrEnd.offset(),
847 regionManager_.physicalOffset(addrEnd), sizeof(EntryDesc),
848 folly::hexlify(
849 folly::ByteRange(entryEnd - sizeof(EntryDesc), entryEnd)));
850 return std::nullopt;
851 }
852 buffer = regionManager_.read(desc, addrEnd.sub(readSize), readSize);
853 if (buffer.isNull()) {
854 return std::nullopt;
855 }
856
857 // modify the address for these variables accordingly
858 entryEnd = buffer.data() + buffer.size();

Callers

nothing calls this directly

Calls 15

HashedKeyClass · 0.85
ridMethod · 0.80
statusMethod · 0.80
physicalOffsetMethod · 0.80
openForReadMethod · 0.45
closeMethod · 0.45
offsetMethod · 0.45
readMethod · 0.45
subMethod · 0.45
isNullMethod · 0.45
dataMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected