table_properties_collector.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // This file defines a collection of statistics collectors.
  7. #pragma once
  8. #include <memory>
  9. #include <string>
  10. #include <vector>
  11. #include "db/dbformat.h"
  12. #include "rocksdb/comparator.h"
  13. #include "rocksdb/table_properties.h"
  14. namespace ROCKSDB_NAMESPACE {
  15. // Base class for internal table properties collector.
  16. class InternalTblPropColl {
  17. public:
  18. virtual ~InternalTblPropColl() {}
  19. virtual Status Finish(UserCollectedProperties* properties) = 0;
  20. virtual const char* Name() const = 0;
  21. // @params key the user key that is inserted into the table.
  22. // @params value the value that is inserted into the table.
  23. virtual Status InternalAdd(const Slice& key, const Slice& value,
  24. uint64_t file_size) = 0;
  25. virtual void BlockAdd(uint64_t block_uncomp_bytes,
  26. uint64_t block_compressed_bytes_fast,
  27. uint64_t block_compressed_bytes_slow) = 0;
  28. virtual UserCollectedProperties GetReadableProperties() const = 0;
  29. virtual bool NeedCompact() const { return false; }
  30. };
  31. // Factory for internal table properties collector.
  32. class InternalTblPropCollFactory {
  33. public:
  34. virtual ~InternalTblPropCollFactory() {}
  35. // has to be thread-safe
  36. virtual InternalTblPropColl* CreateInternalTblPropColl(
  37. uint32_t column_family_id, int level_at_creation, int num_levels,
  38. SequenceNumber last_level_inclusive_max_seqno_threshold =
  39. kMaxSequenceNumber) = 0;
  40. // The name of the properties collector can be used for debugging purpose.
  41. virtual const char* Name() const = 0;
  42. };
  43. using InternalTblPropCollFactories =
  44. std::vector<std::unique_ptr<InternalTblPropCollFactory>>;
  45. // When rocksdb creates a new table, it will encode all "user keys" into
  46. // "internal keys", which contains meta information of a given entry.
  47. //
  48. // This class extracts user key from the encoded internal key when Add() is
  49. // invoked.
  50. class UserKeyTablePropertiesCollector : public InternalTblPropColl {
  51. public:
  52. // transfer of ownership
  53. explicit UserKeyTablePropertiesCollector(TablePropertiesCollector* collector)
  54. : collector_(collector) {}
  55. virtual ~UserKeyTablePropertiesCollector() {}
  56. Status InternalAdd(const Slice& key, const Slice& value,
  57. uint64_t file_size) override;
  58. void BlockAdd(uint64_t block_uncomp_bytes,
  59. uint64_t block_compressed_bytes_fast,
  60. uint64_t block_compressed_bytes_slow) override;
  61. Status Finish(UserCollectedProperties* properties) override;
  62. const char* Name() const override { return collector_->Name(); }
  63. UserCollectedProperties GetReadableProperties() const override;
  64. bool NeedCompact() const override { return collector_->NeedCompact(); }
  65. protected:
  66. std::unique_ptr<TablePropertiesCollector> collector_;
  67. };
  68. class UserKeyTablePropertiesCollectorFactory
  69. : public InternalTblPropCollFactory {
  70. public:
  71. explicit UserKeyTablePropertiesCollectorFactory(
  72. std::shared_ptr<TablePropertiesCollectorFactory> user_collector_factory)
  73. : user_collector_factory_(user_collector_factory) {}
  74. InternalTblPropColl* CreateInternalTblPropColl(
  75. uint32_t column_family_id, int level_at_creation, int num_levels,
  76. SequenceNumber last_level_inclusive_max_seqno_threshold =
  77. kMaxSequenceNumber) override {
  78. TablePropertiesCollectorFactory::Context context;
  79. context.column_family_id = column_family_id;
  80. context.level_at_creation = level_at_creation;
  81. context.num_levels = num_levels;
  82. context.last_level_inclusive_max_seqno_threshold =
  83. last_level_inclusive_max_seqno_threshold;
  84. TablePropertiesCollector* collector =
  85. user_collector_factory_->CreateTablePropertiesCollector(context);
  86. if (collector) {
  87. return new UserKeyTablePropertiesCollector(collector);
  88. } else {
  89. return nullptr;
  90. }
  91. }
  92. const char* Name() const override { return user_collector_factory_->Name(); }
  93. private:
  94. std::shared_ptr<TablePropertiesCollectorFactory> user_collector_factory_;
  95. };
  96. // When rocksdb creates a newtable, it will encode all "user keys" into
  97. // "internal keys". This class collects min/max timestamp from the encoded
  98. // internal key when Add() is invoked.
  99. //
  100. // @param cmp the user comparator to compare the timestamps in internal key.
  101. class TimestampTablePropertiesCollector : public InternalTblPropColl {
  102. public:
  103. explicit TimestampTablePropertiesCollector(const Comparator* cmp)
  104. : cmp_(cmp),
  105. timestamp_min_(kDisableUserTimestamp),
  106. timestamp_max_(kDisableUserTimestamp) {}
  107. Status InternalAdd(const Slice& key, const Slice& /* value */,
  108. uint64_t /* file_size */) override {
  109. auto user_key = ExtractUserKey(key);
  110. assert(cmp_ && cmp_->timestamp_size() > 0);
  111. if (user_key.size() < cmp_->timestamp_size()) {
  112. return Status::Corruption(
  113. "User key size mismatch when comparing to timestamp size.");
  114. }
  115. auto timestamp_in_key =
  116. ExtractTimestampFromUserKey(user_key, cmp_->timestamp_size());
  117. if (timestamp_max_ == kDisableUserTimestamp ||
  118. cmp_->CompareTimestamp(timestamp_in_key, timestamp_max_) > 0) {
  119. timestamp_max_.assign(timestamp_in_key.data(), timestamp_in_key.size());
  120. }
  121. if (timestamp_min_ == kDisableUserTimestamp ||
  122. cmp_->CompareTimestamp(timestamp_min_, timestamp_in_key) > 0) {
  123. timestamp_min_.assign(timestamp_in_key.data(), timestamp_in_key.size());
  124. }
  125. return Status::OK();
  126. }
  127. void BlockAdd(uint64_t /* block_uncomp_bytes */,
  128. uint64_t /* block_compressed_bytes_fast */,
  129. uint64_t /* block_compressed_bytes_slow */) override {
  130. return;
  131. }
  132. Status Finish(UserCollectedProperties* properties) override {
  133. // timestamp is empty is table is empty
  134. assert(timestamp_min_.size() == timestamp_max_.size() &&
  135. (timestamp_min_.empty() ||
  136. timestamp_max_.size() == cmp_->timestamp_size()));
  137. properties->insert({"rocksdb.timestamp_min", timestamp_min_});
  138. properties->insert({"rocksdb.timestamp_max", timestamp_max_});
  139. return Status::OK();
  140. }
  141. const char* Name() const override {
  142. return "TimestampTablePropertiesCollector";
  143. }
  144. UserCollectedProperties GetReadableProperties() const override {
  145. return {{"rocksdb.timestamp_min", Slice(timestamp_min_).ToString(true)},
  146. {"rocksdb.timestamp_max", Slice(timestamp_max_).ToString(true)}};
  147. }
  148. protected:
  149. const Comparator* const cmp_;
  150. std::string timestamp_min_;
  151. std::string timestamp_max_;
  152. };
  153. } // namespace ROCKSDB_NAMESPACE