| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #include "db/blob/blob_garbage_meter.h"
- #include "db/blob/blob_index.h"
- #include "db/blob/blob_log_format.h"
- #include "db/dbformat.h"
- namespace ROCKSDB_NAMESPACE {
- Status BlobGarbageMeter::ProcessInFlow(const Slice& key, const Slice& value) {
- uint64_t blob_file_number = kInvalidBlobFileNumber;
- uint64_t bytes = 0;
- const Status s = Parse(key, value, &blob_file_number, &bytes);
- if (!s.ok()) {
- return s;
- }
- if (blob_file_number == kInvalidBlobFileNumber) {
- return Status::OK();
- }
- flows_[blob_file_number].AddInFlow(bytes);
- return Status::OK();
- }
- Status BlobGarbageMeter::ProcessOutFlow(const Slice& key, const Slice& value) {
- uint64_t blob_file_number = kInvalidBlobFileNumber;
- uint64_t bytes = 0;
- const Status s = Parse(key, value, &blob_file_number, &bytes);
- if (!s.ok()) {
- return s;
- }
- if (blob_file_number == kInvalidBlobFileNumber) {
- return Status::OK();
- }
- // Note: in order to measure the amount of additional garbage, we only need to
- // track the outflow for preexisting files, i.e. those that also had inflow.
- // (Newly written files would only have outflow.)
- auto it = flows_.find(blob_file_number);
- if (it == flows_.end()) {
- return Status::OK();
- }
- it->second.AddOutFlow(bytes);
- return Status::OK();
- }
- Status BlobGarbageMeter::Parse(const Slice& key, const Slice& value,
- uint64_t* blob_file_number, uint64_t* bytes) {
- assert(blob_file_number);
- assert(*blob_file_number == kInvalidBlobFileNumber);
- assert(bytes);
- assert(*bytes == 0);
- ParsedInternalKey ikey;
- {
- constexpr bool log_err_key = false;
- const Status s = ParseInternalKey(key, &ikey, log_err_key);
- if (!s.ok()) {
- return s;
- }
- }
- if (ikey.type != kTypeBlobIndex) {
- return Status::OK();
- }
- BlobIndex blob_index;
- {
- const Status s = blob_index.DecodeFrom(value);
- if (!s.ok()) {
- return s;
- }
- }
- if (blob_index.IsInlined() || blob_index.HasTTL()) {
- return Status::Corruption("Unexpected TTL/inlined blob index");
- }
- *blob_file_number = blob_index.file_number();
- *bytes =
- blob_index.size() +
- BlobLogRecord::CalculateAdjustmentForRecordHeader(ikey.user_key.size());
- return Status::OK();
- }
- } // namespace ROCKSDB_NAMESPACE
|