github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/c-deps/libroach/table_props.cc (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  #include "table_props.h"
    12  #include <rocksdb/slice.h>
    13  #include <rocksdb/status.h>
    14  #include <rocksdb/table_properties.h>
    15  #include <rocksdb/types.h>
    16  #include "encoding.h"
    17  
    18  namespace cockroach {
    19  
    20  namespace {
    21  
    22  // This is re-implemented in sst_writer.go and should be kept in sync.
    23  class TimeBoundTblPropCollector : public rocksdb::TablePropertiesCollector {
    24   public:
    25    const char* Name() const override { return "TimeBoundTblPropCollector"; }
    26  
    27    rocksdb::Status Finish(rocksdb::UserCollectedProperties* properties) override {
    28      if (!last_value_.empty()) {
    29        // Check to see if an intent was the last key in the SSTable. If
    30        // it was, we need to extract the timestamp from the intent and
    31        // update the bounds to include that timestamp.
    32        cockroach::storage::enginepb::MVCCMetadata meta;
    33        if (!meta.ParseFromArray(last_value_.data(), last_value_.size())) {
    34          // We're unable to parse the MVCCMetadata. Fail open by not
    35          // setting the min/max timestamp properties.
    36          return rocksdb::Status::OK();
    37        }
    38        if (meta.has_txn()) {
    39          // We have an intent, use the intent's timestamp to update the
    40          // timestamp bounds.
    41          std::string ts;
    42          EncodeTimestamp(ts, meta.timestamp().wall_time(), meta.timestamp().logical());
    43          UpdateBounds(ts);
    44        }
    45      }
    46  
    47      *properties = rocksdb::UserCollectedProperties{
    48          {"crdb.ts.min", ts_min_},
    49          {"crdb.ts.max", ts_max_},
    50      };
    51      return rocksdb::Status::OK();
    52    }
    53  
    54    rocksdb::Status AddUserKey(const rocksdb::Slice& user_key, const rocksdb::Slice& value,
    55                               rocksdb::EntryType type, rocksdb::SequenceNumber seq,
    56                               uint64_t file_size) override {
    57      rocksdb::Slice unused;
    58      rocksdb::Slice ts;
    59      if (!SplitKey(user_key, &unused, &ts)) {
    60        return rocksdb::Status::OK();
    61      }
    62  
    63      if (!ts.empty()) {
    64        last_value_.clear();
    65        ts.remove_prefix(1);  // The NUL prefix.
    66        UpdateBounds(ts);
    67        return rocksdb::Status::OK();
    68      }
    69  
    70      last_value_.assign(value.data(), value.size());
    71      return rocksdb::Status::OK();
    72    }
    73  
    74    virtual rocksdb::UserCollectedProperties GetReadableProperties() const override {
    75      return rocksdb::UserCollectedProperties{};
    76    }
    77  
    78   private:
    79    void UpdateBounds(rocksdb::Slice ts) {
    80      if (ts_max_.empty() || ts.compare(ts_max_) > 0) {
    81        ts_max_.assign(ts.data(), ts.size());
    82      }
    83      if (ts_min_.empty() || ts.compare(ts_min_) < 0) {
    84        ts_min_.assign(ts.data(), ts.size());
    85      }
    86    }
    87  
    88   private:
    89    std::string ts_min_;
    90    std::string ts_max_;
    91    std::string last_value_;
    92  };
    93  
    94  class TimeBoundTblPropCollectorFactory : public rocksdb::TablePropertiesCollectorFactory {
    95   public:
    96    explicit TimeBoundTblPropCollectorFactory() {}
    97    virtual rocksdb::TablePropertiesCollector* CreateTablePropertiesCollector(
    98        rocksdb::TablePropertiesCollectorFactory::Context context) override {
    99      return new TimeBoundTblPropCollector();
   100    }
   101    const char* Name() const override { return "TimeBoundTblPropCollectorFactory"; }
   102  };
   103  
   104  class DeleteRangeTblPropCollector : public rocksdb::TablePropertiesCollector {
   105   public:
   106    const char* Name() const override { return "DeleteRangeTblPropCollector"; }
   107  
   108    rocksdb::Status Finish(rocksdb::UserCollectedProperties*) override {
   109      return rocksdb::Status::OK();
   110    }
   111  
   112    rocksdb::Status AddUserKey(const rocksdb::Slice&, const rocksdb::Slice&, rocksdb::EntryType type,
   113                               rocksdb::SequenceNumber, uint64_t) override {
   114      if (type == rocksdb::kEntryRangeDeletion) {
   115        ntombstones_++;
   116      }
   117      return rocksdb::Status::OK();
   118    }
   119  
   120    virtual rocksdb::UserCollectedProperties GetReadableProperties() const override {
   121      return rocksdb::UserCollectedProperties{};
   122    }
   123  
   124    virtual bool NeedCompact() const override {
   125      // NB: Mark any file containing range deletions as requiring a
   126      // compaction. This ensures that range deletions are quickly compacted out
   127      // of existence.
   128      return ntombstones_ > 0;
   129    }
   130  
   131   private:
   132    int ntombstones_ = 0;
   133  };
   134  
   135  class DeleteRangeTblPropCollectorFactory : public rocksdb::TablePropertiesCollectorFactory {
   136    virtual rocksdb::TablePropertiesCollector* CreateTablePropertiesCollector(
   137        rocksdb::TablePropertiesCollectorFactory::Context context) override {
   138      return new DeleteRangeTblPropCollector();
   139    }
   140    const char* Name() const override { return "DeleteRangeTblPropCollectorFactory"; }
   141  };
   142  
   143  }  // namespace
   144  
   145  rocksdb::TablePropertiesCollectorFactory* DBMakeTimeBoundCollector() {
   146    return new TimeBoundTblPropCollectorFactory();
   147  }
   148  
   149  rocksdb::TablePropertiesCollectorFactory* DBMakeDeleteRangeCollector() {
   150    return new DeleteRangeTblPropCollectorFactory();
   151  }
   152  
   153  }  // namespace cockroach