db_ttl_impl.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  2. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style license that can be
  4. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  5. #pragma once
  6. #include <deque>
  7. #include <string>
  8. #include <vector>
  9. #include "db/db_impl/db_impl.h"
  10. #include "rocksdb/compaction_filter.h"
  11. #include "rocksdb/db.h"
  12. #include "rocksdb/merge_operator.h"
  13. #include "rocksdb/system_clock.h"
  14. #include "rocksdb/utilities/db_ttl.h"
  15. #include "utilities/compaction_filters/layered_compaction_filter_base.h"
  16. #ifdef _WIN32
  17. // Windows API macro interference
  18. #undef GetCurrentTime
  19. #endif
  20. namespace ROCKSDB_NAMESPACE {
  21. struct ConfigOptions;
  22. class ObjectLibrary;
  23. class ObjectRegistry;
  24. class DBWithTTLImpl : public DBWithTTL {
  25. public:
  26. static void SanitizeOptions(int32_t ttl, ColumnFamilyOptions* options,
  27. SystemClock* clock);
  28. static void RegisterTtlClasses();
  29. explicit DBWithTTLImpl(DB* db);
  30. virtual ~DBWithTTLImpl();
  31. Status Close() override;
  32. Status CreateColumnFamilyWithTtl(const ColumnFamilyOptions& options,
  33. const std::string& column_family_name,
  34. ColumnFamilyHandle** handle,
  35. int ttl) override;
  36. Status CreateColumnFamily(const ColumnFamilyOptions& options,
  37. const std::string& column_family_name,
  38. ColumnFamilyHandle** handle) override;
  39. using StackableDB::Put;
  40. Status Put(const WriteOptions& options, ColumnFamilyHandle* column_family,
  41. const Slice& key, const Slice& val) override;
  42. using StackableDB::Get;
  43. Status Get(const ReadOptions& options, ColumnFamilyHandle* column_family,
  44. const Slice& key, PinnableSlice* value,
  45. std::string* timestamp) override;
  46. using StackableDB::MultiGet;
  47. void MultiGet(const ReadOptions& options, const size_t num_keys,
  48. ColumnFamilyHandle** column_families, const Slice* keys,
  49. PinnableSlice* values, std::string* timestamps,
  50. Status* statuses, const bool sorted_input) override;
  51. using StackableDB::KeyMayExist;
  52. bool KeyMayExist(const ReadOptions& options,
  53. ColumnFamilyHandle* column_family, const Slice& key,
  54. std::string* value, bool* value_found = nullptr) override;
  55. using StackableDB::Merge;
  56. Status Merge(const WriteOptions& options, ColumnFamilyHandle* column_family,
  57. const Slice& key, const Slice& value) override;
  58. Status Write(const WriteOptions& opts, WriteBatch* updates) override;
  59. using StackableDB::NewIterator;
  60. Iterator* NewIterator(const ReadOptions& _read_options,
  61. ColumnFamilyHandle* column_family) override;
  62. DB* GetBaseDB() override { return db_; }
  63. static bool IsStale(const Slice& value, int32_t ttl, SystemClock* clock);
  64. static Status AppendTS(const Slice& val, std::string* val_with_ts,
  65. SystemClock* clock);
  66. static Status SanityCheckTimestamp(const Slice& str);
  67. static Status StripTS(std::string* str);
  68. static Status StripTS(PinnableSlice* str);
  69. static const uint32_t kTSLength = sizeof(int32_t); // size of timestamp
  70. static const int32_t kMinTimestamp = 1368146402; // 05/09/2013:5:40PM GMT-8
  71. static const int32_t kMaxTimestamp = 2147483647; // 01/18/2038:7:14PM GMT-8
  72. void SetTtl(int32_t ttl) override { SetTtl(DefaultColumnFamily(), ttl); }
  73. void SetTtl(ColumnFamilyHandle* h, int32_t ttl) override;
  74. Status GetTtl(ColumnFamilyHandle* h, int32_t* ttl) override;
  75. private:
  76. // remember whether the Close completes or not
  77. bool closed_;
  78. };
  79. class TtlIterator : public Iterator {
  80. public:
  81. explicit TtlIterator(Iterator* iter) : iter_(iter) { assert(iter_); }
  82. ~TtlIterator() { delete iter_; }
  83. bool Valid() const override { return iter_->Valid(); }
  84. void SeekToFirst() override { iter_->SeekToFirst(); }
  85. void SeekToLast() override { iter_->SeekToLast(); }
  86. void Seek(const Slice& target) override { iter_->Seek(target); }
  87. void SeekForPrev(const Slice& target) override { iter_->SeekForPrev(target); }
  88. void Next() override { iter_->Next(); }
  89. void Prev() override { iter_->Prev(); }
  90. Slice key() const override { return iter_->key(); }
  91. int32_t ttl_timestamp() const {
  92. return DecodeFixed32(iter_->value().data() + iter_->value().size() -
  93. DBWithTTLImpl::kTSLength);
  94. }
  95. Slice value() const override {
  96. // TODO: handle timestamp corruption like in general iterator semantics
  97. assert(DBWithTTLImpl::SanityCheckTimestamp(iter_->value()).ok());
  98. Slice trimmed_value = iter_->value();
  99. trimmed_value.size_ -= DBWithTTLImpl::kTSLength;
  100. return trimmed_value;
  101. }
  102. Status status() const override { return iter_->status(); }
  103. private:
  104. Iterator* iter_;
  105. };
  106. class TtlCompactionFilter : public LayeredCompactionFilterBase {
  107. public:
  108. TtlCompactionFilter(int32_t ttl, SystemClock* clock,
  109. const CompactionFilter* _user_comp_filter,
  110. std::unique_ptr<const CompactionFilter>
  111. _user_comp_filter_from_factory = nullptr);
  112. bool Filter(int level, const Slice& key, const Slice& old_val,
  113. std::string* new_val, bool* value_changed) const override;
  114. const char* Name() const override { return kClassName(); }
  115. static const char* kClassName() { return "TtlCompactionFilter"; }
  116. bool IsInstanceOf(const std::string& name) const override {
  117. if (name == "Delete By TTL") {
  118. return true;
  119. } else {
  120. return LayeredCompactionFilterBase::IsInstanceOf(name);
  121. }
  122. }
  123. Status PrepareOptions(const ConfigOptions& config_options) override;
  124. Status ValidateOptions(const DBOptions& db_opts,
  125. const ColumnFamilyOptions& cf_opts) const override;
  126. private:
  127. int32_t ttl_;
  128. SystemClock* clock_;
  129. };
  130. class TtlCompactionFilterFactory : public CompactionFilterFactory {
  131. public:
  132. TtlCompactionFilterFactory(
  133. int32_t ttl, SystemClock* clock,
  134. std::shared_ptr<CompactionFilterFactory> comp_filter_factory);
  135. std::unique_ptr<CompactionFilter> CreateCompactionFilter(
  136. const CompactionFilter::Context& context) override;
  137. void SetTtl(int32_t ttl) { ttl_ = ttl; }
  138. int32_t GetTtl() { return ttl_; }
  139. const char* Name() const override { return kClassName(); }
  140. static const char* kClassName() { return "TtlCompactionFilterFactory"; }
  141. Status PrepareOptions(const ConfigOptions& config_options) override;
  142. Status ValidateOptions(const DBOptions& db_opts,
  143. const ColumnFamilyOptions& cf_opts) const override;
  144. const Customizable* Inner() const override {
  145. return user_comp_filter_factory_.get();
  146. }
  147. private:
  148. int32_t ttl_;
  149. SystemClock* clock_;
  150. std::shared_ptr<CompactionFilterFactory> user_comp_filter_factory_;
  151. };
  152. class TtlMergeOperator : public MergeOperator {
  153. public:
  154. explicit TtlMergeOperator(const std::shared_ptr<MergeOperator>& merge_op,
  155. SystemClock* clock);
  156. bool FullMergeV2(const MergeOperationInput& merge_in,
  157. MergeOperationOutput* merge_out) const override;
  158. bool PartialMergeMulti(const Slice& key,
  159. const std::deque<Slice>& operand_list,
  160. std::string* new_value, Logger* logger) const override;
  161. static const char* kClassName() { return "TtlMergeOperator"; }
  162. const char* Name() const override { return kClassName(); }
  163. bool IsInstanceOf(const std::string& name) const override {
  164. if (name == "Merge By TTL") {
  165. return true;
  166. } else {
  167. return MergeOperator::IsInstanceOf(name);
  168. }
  169. }
  170. Status PrepareOptions(const ConfigOptions& config_options) override;
  171. Status ValidateOptions(const DBOptions& db_opts,
  172. const ColumnFamilyOptions& cf_opts) const override;
  173. const Customizable* Inner() const override { return user_merge_op_.get(); }
  174. private:
  175. std::shared_ptr<MergeOperator> user_merge_op_;
  176. SystemClock* clock_;
  177. };
  178. extern "C" {
  179. int RegisterTtlObjects(ObjectLibrary& library, const std::string& /*arg*/);
  180. } // extern "C"
  181. } // namespace ROCKSDB_NAMESPACE