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).
6 // This file defines a collection of statistics collectors.
13 #include "db/dbformat.h"
14 #include "rocksdb/comparator.h"
15 #include "rocksdb/table_properties.h"
17 namespace ROCKSDB_NAMESPACE
{
19 // Base class for internal table properties collector.
20 class IntTblPropCollector
{
22 virtual ~IntTblPropCollector() {}
23 virtual Status
Finish(UserCollectedProperties
* properties
) = 0;
25 virtual const char* Name() const = 0;
27 // @params key the user key that is inserted into the table.
28 // @params value the value that is inserted into the table.
29 virtual Status
InternalAdd(const Slice
& key
, const Slice
& value
,
30 uint64_t file_size
) = 0;
32 virtual void BlockAdd(uint64_t block_uncomp_bytes
,
33 uint64_t block_compressed_bytes_fast
,
34 uint64_t block_compressed_bytes_slow
) = 0;
36 virtual UserCollectedProperties
GetReadableProperties() const = 0;
38 virtual bool NeedCompact() const { return false; }
41 // Factory for internal table properties collector.
42 class IntTblPropCollectorFactory
{
44 virtual ~IntTblPropCollectorFactory() {}
45 // has to be thread-safe
46 virtual IntTblPropCollector
* CreateIntTblPropCollector(
47 uint32_t column_family_id
, int level_at_creation
) = 0;
49 // The name of the properties collector can be used for debugging purpose.
50 virtual const char* Name() const = 0;
53 using IntTblPropCollectorFactories
=
54 std::vector
<std::unique_ptr
<IntTblPropCollectorFactory
>>;
56 // When rocksdb creates a new table, it will encode all "user keys" into
57 // "internal keys", which contains meta information of a given entry.
59 // This class extracts user key from the encoded internal key when Add() is
61 class UserKeyTablePropertiesCollector
: public IntTblPropCollector
{
63 // transfer of ownership
64 explicit UserKeyTablePropertiesCollector(TablePropertiesCollector
* collector
)
65 : collector_(collector
) {}
67 virtual ~UserKeyTablePropertiesCollector() {}
69 virtual Status
InternalAdd(const Slice
& key
, const Slice
& value
,
70 uint64_t file_size
) override
;
72 virtual void BlockAdd(uint64_t block_uncomp_bytes
,
73 uint64_t block_compressed_bytes_fast
,
74 uint64_t block_compressed_bytes_slow
) override
;
76 virtual Status
Finish(UserCollectedProperties
* properties
) override
;
78 virtual const char* Name() const override
{ return collector_
->Name(); }
80 UserCollectedProperties
GetReadableProperties() const override
;
82 virtual bool NeedCompact() const override
{
83 return collector_
->NeedCompact();
87 std::unique_ptr
<TablePropertiesCollector
> collector_
;
90 class UserKeyTablePropertiesCollectorFactory
91 : public IntTblPropCollectorFactory
{
93 explicit UserKeyTablePropertiesCollectorFactory(
94 std::shared_ptr
<TablePropertiesCollectorFactory
> user_collector_factory
)
95 : user_collector_factory_(user_collector_factory
) {}
96 virtual IntTblPropCollector
* CreateIntTblPropCollector(
97 uint32_t column_family_id
, int level_at_creation
) override
{
98 TablePropertiesCollectorFactory::Context context
;
99 context
.column_family_id
= column_family_id
;
100 context
.level_at_creation
= level_at_creation
;
101 return new UserKeyTablePropertiesCollector(
102 user_collector_factory_
->CreateTablePropertiesCollector(context
));
105 virtual const char* Name() const override
{
106 return user_collector_factory_
->Name();
110 std::shared_ptr
<TablePropertiesCollectorFactory
> user_collector_factory_
;
113 // When rocksdb creates a newtable, it will encode all "user keys" into
114 // "internal keys". This class collects min/max timestamp from the encoded
115 // internal key when Add() is invoked.
117 // @param cmp the user comparator to compare the timestamps in internal key.
118 class TimestampTablePropertiesCollector
: public IntTblPropCollector
{
120 explicit TimestampTablePropertiesCollector(const Comparator
* cmp
)
122 timestamp_min_(kDisableUserTimestamp
),
123 timestamp_max_(kDisableUserTimestamp
) {}
125 Status
InternalAdd(const Slice
& key
, const Slice
& /* value */,
126 uint64_t /* file_size */) override
{
127 auto user_key
= ExtractUserKey(key
);
128 assert(cmp_
&& cmp_
->timestamp_size() > 0);
129 if (user_key
.size() < cmp_
->timestamp_size()) {
130 return Status::Corruption(
131 "User key size mismatch when comparing to timestamp size.");
133 auto timestamp_in_key
=
134 ExtractTimestampFromUserKey(user_key
, cmp_
->timestamp_size());
135 if (timestamp_max_
== kDisableUserTimestamp
||
136 cmp_
->CompareTimestamp(timestamp_in_key
, timestamp_max_
) > 0) {
137 timestamp_max_
.assign(timestamp_in_key
.data(), timestamp_in_key
.size());
139 if (timestamp_min_
== kDisableUserTimestamp
||
140 cmp_
->CompareTimestamp(timestamp_min_
, timestamp_in_key
) > 0) {
141 timestamp_min_
.assign(timestamp_in_key
.data(), timestamp_in_key
.size());
146 void BlockAdd(uint64_t /* block_uncomp_bytes */,
147 uint64_t /* block_compressed_bytes_fast */,
148 uint64_t /* block_compressed_bytes_slow */) override
{
152 Status
Finish(UserCollectedProperties
* properties
) override
{
153 assert(timestamp_min_
.size() == timestamp_max_
.size() &&
154 timestamp_max_
.size() == cmp_
->timestamp_size());
155 properties
->insert({"rocksdb.timestamp_min", timestamp_min_
});
156 properties
->insert({"rocksdb.timestamp_max", timestamp_max_
});
160 const char* Name() const override
{
161 return "TimestampTablePropertiesCollector";
164 UserCollectedProperties
GetReadableProperties() const override
{
165 return {{"rocksdb.timestamp_min", Slice(timestamp_min_
).ToString(true)},
166 {"rocksdb.timestamp_max", Slice(timestamp_max_
).ToString(true)}};
170 const Comparator
* const cmp_
;
171 std::string timestamp_min_
;
172 std::string timestamp_max_
;
175 } // namespace ROCKSDB_NAMESPACE