1/*
2 Copyright (c) 2015, Facebook, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16#pragma once
17
18/* C++ system header files */
19#include <map>
20#include <memory>
21#include <string>
22#include <unordered_set>
23#include <vector>
24
25/* RocksDB header files */
26#include "rocksdb/db.h"
27
28/* MyRocks header files */
29#include "./ha_rocksdb.h"
30
31namespace myrocks {
32
33class Rdb_ddl_manager;
34class Rdb_key_def;
35
36extern std::atomic<uint64_t> rocksdb_num_sst_entry_put;
37extern std::atomic<uint64_t> rocksdb_num_sst_entry_delete;
38extern std::atomic<uint64_t> rocksdb_num_sst_entry_singledelete;
39extern std::atomic<uint64_t> rocksdb_num_sst_entry_merge;
40extern std::atomic<uint64_t> rocksdb_num_sst_entry_other;
41extern my_bool rocksdb_compaction_sequential_deletes_count_sd;
42
43struct Rdb_compact_params {
44 uint64_t m_deletes, m_window, m_file_size;
45};
46
47struct Rdb_index_stats {
48 enum {
49 INDEX_STATS_VERSION_INITIAL = 1,
50 INDEX_STATS_VERSION_ENTRY_TYPES = 2,
51 };
52 GL_INDEX_ID m_gl_index_id;
53 int64_t m_data_size, m_rows, m_actual_disk_size;
54 int64_t m_entry_deletes, m_entry_single_deletes;
55 int64_t m_entry_merges, m_entry_others;
56 std::vector<int64_t> m_distinct_keys_per_prefix;
57 std::string m_name; // name is not persisted
58
59 static std::string materialize(const std::vector<Rdb_index_stats> &stats);
60 static int unmaterialize(const std::string &s,
61 std::vector<Rdb_index_stats> *const ret);
62
63 Rdb_index_stats() : Rdb_index_stats({0, 0}) {}
64 explicit Rdb_index_stats(GL_INDEX_ID gl_index_id)
65 : m_gl_index_id(gl_index_id), m_data_size(0), m_rows(0),
66 m_actual_disk_size(0), m_entry_deletes(0), m_entry_single_deletes(0),
67 m_entry_merges(0), m_entry_others(0) {}
68
69 void merge(const Rdb_index_stats &s, const bool &increment = true,
70 const int64_t &estimated_data_len = 0);
71};
72
73// The helper class to calculate index cardinality
74class Rdb_tbl_card_coll {
75 public:
76 explicit Rdb_tbl_card_coll(const uint8_t &table_stats_sampling_pct);
77
78 public:
79 void ProcessKey(const rocksdb::Slice &key, const Rdb_key_def *keydef,
80 Rdb_index_stats *stats);
81 /*
82 * Resets the state of the collector to start calculating statistics for a
83 * next index.
84 */
85 void Reset();
86
87 /*
88 * Cardinality statistics might be calculated using some sampling strategy.
89 * This method adjusts gathered statistics according to the sampling
90 * strategy used. Note that adjusted cardinality value is just an estimate
91 * and can return a value exeeding number of rows in a table, so the
92 * returned value should be capped by row count before using it by
93 * an optrimizer or displaying it to a clent.
94 */
95 void AdjustStats(Rdb_index_stats *stats);
96
97 private:
98 bool ShouldCollectStats();
99 bool IsSampingDisabled();
100
101 private:
102 std::string m_last_key;
103 uint8_t m_table_stats_sampling_pct;
104 unsigned int m_seed;
105};
106
107class Rdb_tbl_prop_coll : public rocksdb::TablePropertiesCollector {
108public:
109 Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager,
110 const Rdb_compact_params &params, const uint32_t &cf_id,
111 const uint8_t &table_stats_sampling_pct);
112
113 /*
114 Override parent class's virtual methods of interest.
115 */
116
117 virtual rocksdb::Status AddUserKey(const rocksdb::Slice &key,
118 const rocksdb::Slice &value,
119 rocksdb::EntryType type,
120 rocksdb::SequenceNumber seq,
121 uint64_t file_size);
122
123 virtual rocksdb::Status
124 Finish(rocksdb::UserCollectedProperties *properties) override;
125
126 virtual const char *Name() const override { return "Rdb_tbl_prop_coll"; }
127
128 rocksdb::UserCollectedProperties GetReadableProperties() const override;
129
130 bool NeedCompact() const override;
131
132public:
133 uint64_t GetMaxDeletedRows() const { return m_max_deleted_rows; }
134
135 static void read_stats_from_tbl_props(
136 const std::shared_ptr<const rocksdb::TableProperties> &table_props,
137 std::vector<Rdb_index_stats> *out_stats_vector);
138
139private:
140 static std::string GetReadableStats(const Rdb_index_stats &it);
141
142 bool ShouldCollectStats();
143 void CollectStatsForRow(const rocksdb::Slice &key,
144 const rocksdb::Slice &value,
145 const rocksdb::EntryType &type,
146 const uint64_t &file_size);
147 Rdb_index_stats *AccessStats(const rocksdb::Slice &key);
148 void AdjustDeletedRows(rocksdb::EntryType type);
149
150private:
151 uint32_t m_cf_id;
152 std::shared_ptr<const Rdb_key_def> m_keydef;
153 Rdb_ddl_manager *m_ddl_manager;
154 std::vector<Rdb_index_stats> m_stats;
155 Rdb_index_stats *m_last_stats;
156 static const char *INDEXSTATS_KEY;
157
158 // last added key
159 std::string m_last_key;
160
161 // floating window to count deleted rows
162 std::vector<bool> m_deleted_rows_window;
163 uint64_t m_rows, m_window_pos, m_deleted_rows, m_max_deleted_rows;
164 uint64_t m_file_size;
165 Rdb_compact_params m_params;
166 Rdb_tbl_card_coll m_cardinality_collector;
167};
168
169class Rdb_tbl_prop_coll_factory
170 : public rocksdb::TablePropertiesCollectorFactory {
171public:
172 Rdb_tbl_prop_coll_factory(const Rdb_tbl_prop_coll_factory &) = delete;
173 Rdb_tbl_prop_coll_factory &
174 operator=(const Rdb_tbl_prop_coll_factory &) = delete;
175
176 explicit Rdb_tbl_prop_coll_factory(Rdb_ddl_manager *ddl_manager)
177 : m_ddl_manager(ddl_manager) {}
178
179 /*
180 Override parent class's virtual methods of interest.
181 */
182
183 virtual rocksdb::TablePropertiesCollector *CreateTablePropertiesCollector(
184 rocksdb::TablePropertiesCollectorFactory::Context context) override {
185 return new Rdb_tbl_prop_coll(m_ddl_manager, m_params,
186 context.column_family_id,
187 m_table_stats_sampling_pct);
188 }
189
190 virtual const char *Name() const override {
191 return "Rdb_tbl_prop_coll_factory";
192 }
193
194public:
195 void SetCompactionParams(const Rdb_compact_params &params) {
196 m_params = params;
197 }
198
199 void SetTableStatsSamplingPct(const uint8_t &table_stats_sampling_pct) {
200 m_table_stats_sampling_pct = table_stats_sampling_pct;
201 }
202
203private:
204 Rdb_ddl_manager *const m_ddl_manager;
205 Rdb_compact_params m_params;
206 uint8_t m_table_stats_sampling_pct;
207};
208
209} // namespace myrocks
210