Status BigHash::insert()

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;
}