in cachelib/navy/bighash/BigHash.cpp [232:304]
Status BigHash::insert(HashedKey hk, BufferView value) {
const auto bid = getBucketId(hk);
insertCount_.inc();
uint32_t removed{0};
uint32_t evicted{0};
uint32_t oldRemainingBytes = 0;
uint32_t newRemainingBytes = 0;
// we copy the items and trigger the destructorCb after bucket lock is
// released to avoid possible heavy operations or locks in the destrcutor.
std::vector<std::tuple<Buffer, Buffer, DestructorEvent>> removedItems;
DestructorCallback cb =
[&removedItems](BufferView key, BufferView val, DestructorEvent event) {
removedItems.emplace_back(key, val, event);
};
{
std::unique_lock<folly::SharedMutex> lock{getMutex(bid)};
auto buffer = readBucket(bid);
if (buffer.isNull()) {
ioErrorCount_.inc();
return Status::DeviceError;
}
auto* bucket = reinterpret_cast<Bucket*>(buffer.data());
oldRemainingBytes = bucket->remainingBytes();
removed = bucket->remove(hk, cb);
evicted = bucket->insert(hk, value, cb);
newRemainingBytes = bucket->remainingBytes();
// rebuild / fix the bloom filter before we move the buffer to do the
// actual write
if (bloomFilter_) {
if (removed + evicted == 0) {
// In case nothing was removed or evicted, we can just add
bloomFilter_->set(bid.index(), hk.keyHash());
} else {
bfRebuild(bid, bucket);
}
}
const auto res = writeBucket(bid, std::move(buffer));
if (!res) {
if (bloomFilter_) {
bloomFilter_->clear(bid.index());
}
ioErrorCount_.inc();
return Status::DeviceError;
}
}
for (const auto& item : removedItems) {
destructorCb_(std::get<0>(item).view() /* key */,
std::get<1>(item).view() /* value */,
std::get<2>(item) /* event */);
}
if (oldRemainingBytes < newRemainingBytes) {
usedSizeBytes_.sub(newRemainingBytes - oldRemainingBytes);
} else {
usedSizeBytes_.add(oldRemainingBytes - newRemainingBytes);
}
sizeDist_.addSize(hk.key().size() + value.size());
itemCount_.add(1);
itemCount_.sub(evicted + removed);
evictionCount_.add(evicted);
logicalWrittenCount_.add(hk.key().size() + value.size());
physicalWrittenCount_.add(bucketSize_);
succInsertCount_.inc();
return Status::Ok;
}