22#include <glog/logging.h>
24#include "chain/storage/proto/kv.pb.h"
30 std::optional<RocksDBInfo> config) {
31 if (config == std::nullopt) {
32 config = RocksDBInfo();
34 (*config).set_path(path);
35 return std::make_unique<ResRocksDB>(config);
38std::unique_ptr<Storage>
NewResRocksDB(std::optional<RocksDBInfo> config) {
39 return std::make_unique<ResRocksDB>(config);
43 std::string path =
"/tmp/nexres-rocksdb";
44 if (config.has_value()) {
45 num_threads_ = (*config).num_threads();
46 write_buffer_size_ = (*config).write_buffer_size_mb() << 20;
47 write_batch_size_ = (*config).write_batch_size();
48 if ((*config).path() !=
"") {
49 LOG(ERROR) <<
"Custom path for RocksDB provided in config: "
51 path = (*config).path();
57void ResRocksDB::CreateDB(
const std::string& path) {
58 rocksdb::Options options;
59 options.create_if_missing =
true;
60 if (num_threads_ > 1) options.IncreaseParallelism(num_threads_);
61 options.OptimizeLevelStyleCompaction();
62 options.write_buffer_size = write_buffer_size_;
64 rocksdb::DB* db =
nullptr;
65 rocksdb::Status status = rocksdb::DB::Open(options, path, &db);
67 db_ = std::unique_ptr<rocksdb::DB>(db);
68 LOG(ERROR) <<
"Successfully opened RocksDB in path: " << path;
70 LOG(ERROR) <<
"RocksDB status fail";
73 LOG(ERROR) <<
"Successfully opened RocksDB";
83 batch_.Put(key, value);
85 if (batch_.Count() >= write_batch_size_) {
86 rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_);
90 LOG(ERROR) <<
"write value fail:" << status.ToString();
98 std::string value =
"";
99 rocksdb::Status status = db_->Get(rocksdb::ReadOptions(), key, &value);
108 std::string values =
"[";
109 rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions());
110 bool first_iteration =
true;
111 for (itr->SeekToFirst(); itr->Valid(); itr->Next()) {
112 if (!first_iteration) values.append(
",");
113 first_iteration =
false;
114 values.append(itr->value().ToString());
123 const std::string& max_key) {
124 std::string values =
"[";
125 rocksdb::Iterator* itr = db_->NewIterator(rocksdb::ReadOptions());
126 bool first_iteration =
true;
127 for (itr->Seek(min_key); itr->Valid() && itr->key().ToString() <= max_key;
129 if (!first_iteration) values.append(
",");
130 first_iteration =
false;
131 values.append(itr->value().ToString());
140 rocksdb::Status status = db_->Write(rocksdb::WriteOptions(), &batch_);
145 LOG(ERROR) <<
"write value fail:" << status.ToString();
149 const std::string& value,
int version) {
150 std::string value_str =
GetValue(key);
151 ValueHistory history;
152 if (!history.ParseFromString(value_str)) {
153 LOG(ERROR) <<
"old_value parse fail";
158 if (history.value_size() > 0) {
159 last_v = history.value(history.value_size() - 1).version();
162 if (last_v != version) {
163 LOG(ERROR) <<
"version does not match:" << version
164 <<
" old version:" << last_v;
168 Value* new_value = history.add_value();
169 new_value->set_value(value);
170 new_value->set_version(version + 1);
172 history.SerializeToString(&value_str);
177 const std::string& key,
int version) {
178 std::string value_str =
GetValue(key);
179 ValueHistory history;
180 if (!history.ParseFromString(value_str)) {
181 LOG(ERROR) <<
"old_value parse fail";
182 return std::make_pair(
"", 0);
184 if (history.value_size() == 0) {
185 return std::make_pair(
"", 0);
188 for (
int i = history.value_size() - 1; i >= 0; --i) {
189 if (history.value(i).version() == version) {
190 return std::make_pair(history.value(i).value(),
191 history.value(i).version());
193 if (history.value(i).version() < version) {
198 int last_idx = history.value_size() - 1;
199 return std::make_pair(history.value(last_idx).value(),
200 history.value(last_idx).version());
205 std::map<std::string, std::pair<std::string, int>> resp;
207 rocksdb::Iterator* it = db_->NewIterator(rocksdb::ReadOptions());
208 for (it->SeekToFirst(); it->Valid(); it->Next()) {
209 ValueHistory history;
210 if (!history.ParseFromString(it->value().ToString()) ||
211 history.value_size() == 0) {
212 LOG(ERROR) <<
"old_value parse fail";
215 const Value& value = history.value(history.value_size() - 1);
216 resp.insert(std::make_pair(it->key().ToString(),
217 std::make_pair(value.value(), value.version())));
225 const std::string& min_key,
const std::string& max_key) {
226 std::map<std::string, std::pair<std::string, int>> resp;
228 rocksdb::Iterator* it = db_->NewIterator(rocksdb::ReadOptions());
229 for (it->Seek(min_key); it->Valid() && it->key().ToString() <= max_key;
231 ValueHistory history;
232 if (!history.ParseFromString(it->value().ToString()) ||
233 history.value_size() == 0) {
234 LOG(ERROR) <<
"old_value parse fail";
237 const Value& value = history.value(history.value_size() - 1);
238 resp.insert(std::make_pair(it->key().ToString(),
239 std::make_pair(value.value(), value.version())));
248 const std::string& key,
int min_version,
int max_version) {
249 std::vector<std::pair<std::string, int>> resp;
250 std::string value_str =
GetValue(key);
251 ValueHistory history;
252 if (!history.ParseFromString(value_str)) {
253 LOG(ERROR) <<
"old_value parse fail";
257 for (
int i = history.value_size() - 1; i >= 0; --i) {
258 if (history.value(i).version() < min_version) {
261 if (history.value(i).version() <= max_version) {
263 std::make_pair(history.value(i).value(), history.value(i).version()));
272 const std::string& key,
int top_number) {
273 std::vector<std::pair<std::string, int>> resp;
274 std::string value_str =
GetValue(key);
275 ValueHistory history;
276 if (!history.ParseFromString(value_str)) {
277 LOG(ERROR) <<
"old_value parse fail";
281 for (
int i = history.value_size() - 1;
282 i >= 0 && resp.size() <
static_cast<size_t>(top_number); --i) {
284 std::make_pair(history.value(i).value(), history.value(i).version()));
std::pair< std::string, int > GetValueWithVersion(const std::string &key, int version) override
int SetValue(const std::string &key, const std::string &value) override
std::map< std::string, std::pair< std::string, int > > GetKeyRange(const std::string &min_key, const std::string &max_key) override
std::vector< std::pair< std::string, int > > GetHistory(const std::string &key, int min_version, int max_version) override
int SetValueWithVersion(const std::string &key, const std::string &value, int version) override
std::string GetValue(const std::string &key) override
std::string GetAllValues(void) override
ResRocksDB(std::optional< RocksDBInfo > config_data=std::nullopt)
std::vector< std::pair< std::string, int > > GetTopHistory(const std::string &key, int top_number) override
std::string GetRange(const std::string &min_key, const std::string &max_key) override
std::map< std::string, std::pair< std::string, int > > GetAllItems() override
std::unique_ptr< Storage > storage
std::unique_ptr< Storage > NewResRocksDB(const std::string &path, std::optional< RocksDBInfo > config)