1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

serialize boc with bfs (with multiget)

This commit is contained in:
Marat S 2025-02-12 19:08:57 +00:00
parent 3c245c6146
commit fbb9954391
14 changed files with 448 additions and 122 deletions

View file

@ -20,14 +20,19 @@
#include "td/utils/Status.h"
#include "td/utils/Time.h"
#include "td/utils/logging.h"
#include "td/utils/Span.h"
#include <functional>
namespace td {
enum class DbOpenMode { db_primary, db_secondary, db_readonly };
class KeyValueReader {
public:
virtual ~KeyValueReader() = default;
enum class GetStatus : int32 { Ok, NotFound };
virtual Result<GetStatus> get(Slice key, std::string &value) = 0;
virtual Result<std::vector<GetStatus>> get_multi(td::Span<Slice> keys, std::vector<std::string> *values) = 0;
virtual Result<size_t> count(Slice prefix) = 0;
virtual Status for_each(std::function<Status(Slice, Slice)> f) {
return Status::Error("for_each is not supported");
@ -45,6 +50,14 @@ class PrefixedKeyValueReader : public KeyValueReader {
Result<GetStatus> get(Slice key, std::string &value) override {
return reader_->get(PSLICE() << prefix_ << key, value);
}
Result<std::vector<GetStatus>> get_multi(td::Span<Slice> keys, std::vector<std::string> *values) override {
std::vector<Slice> prefixed_keys;
prefixed_keys.reserve(keys.size());
for (auto &key : keys) {
prefixed_keys.push_back(PSLICE() << prefix_ << key);
}
return reader_->get_multi(prefixed_keys, values);
}
Result<size_t> count(Slice prefix) override {
return reader_->count(PSLICE() << prefix_ << prefix);
}
@ -88,6 +101,14 @@ class PrefixedKeyValue : public KeyValue {
Result<GetStatus> get(Slice key, std::string &value) override {
return kv_->get(PSLICE() << prefix_ << key, value);
}
Result<std::vector<GetStatus>> get_multi(td::Span<Slice> keys, std::vector<std::string> *values) override {
std::vector<Slice> prefixed_keys;
prefixed_keys.reserve(keys.size());
for (auto &key : keys) {
prefixed_keys.push_back(PSLICE() << prefix_ << key);
}
return kv_->get_multi(prefixed_keys, values);
}
Result<size_t> count(Slice prefix) override {
return kv_->count(PSLICE() << prefix_ << prefix);
}

View file

@ -19,6 +19,7 @@
#include "td/db/MemoryKeyValue.h"
#include "td/utils/format.h"
#include "td/utils/Span.h"
namespace td {
Result<MemoryKeyValue::GetStatus> MemoryKeyValue::get(Slice key, std::string &value) {
@ -30,6 +31,23 @@ Result<MemoryKeyValue::GetStatus> MemoryKeyValue::get(Slice key, std::string &va
return GetStatus::Ok;
}
Result<std::vector<MemoryKeyValue::GetStatus>> MemoryKeyValue::get_multi(td::Span<Slice> keys,
std::vector<std::string> *values) {
values->resize(keys.size());
std::vector<GetStatus> res;
for (size_t i = 0; i < keys.size(); i++) {
auto it = map_.find(keys[i]);
if (it == map_.end()) {
res.push_back(GetStatus::NotFound);
(*values)[i] = "";
} else {
res.push_back(GetStatus::Ok);
(*values)[i] = it->second;
}
}
return res;
}
Status MemoryKeyValue::for_each(std::function<Status(Slice, Slice)> f) {
for (auto &it : map_) {
TRY_STATUS(f(it.first, it.second));

View file

@ -25,6 +25,7 @@ namespace td {
class MemoryKeyValue : public KeyValue {
public:
Result<GetStatus> get(Slice key, std::string &value) override;
Result<std::vector<GetStatus>> get_multi(td::Span<Slice> keys, std::vector<std::string> *values) override;
Status for_each(std::function<Status(Slice, Slice)> f) override;
Status for_each_in_range(Slice begin, Slice end, std::function<Status(Slice, Slice)> f) override;
Status set(Slice key, Slice value) override;

View file

@ -153,6 +153,40 @@ Result<RocksDb::GetStatus> RocksDb::get(Slice key, std::string &value) {
return from_rocksdb(status);
}
Result<std::vector<RocksDb::GetStatus>> RocksDb::get_multi(td::Span<Slice> keys, std::vector<std::string> *values) {
std::vector<rocksdb::Status> statuses(keys.size());
std::vector<rocksdb::Slice> keys_rocksdb;
keys_rocksdb.reserve(keys.size());
for (auto &key : keys) {
keys_rocksdb.push_back(to_rocksdb(key));
}
std::vector<rocksdb::PinnableSlice> values_rocksdb(keys.size());
rocksdb::ReadOptions options;
if (snapshot_) {
options.snapshot = snapshot_.get();
db_->MultiGet(options, db_->DefaultColumnFamily(), keys_rocksdb.size(), keys_rocksdb.data(), values_rocksdb.data(), statuses.data());
} else if (transaction_) {
transaction_->MultiGet(options, db_->DefaultColumnFamily(), keys_rocksdb.size(), keys_rocksdb.data(), values_rocksdb.data(), statuses.data());
} else {
db_->MultiGet(options, db_->DefaultColumnFamily(), keys_rocksdb.size(), keys_rocksdb.data(), values_rocksdb.data(), statuses.data());
}
std::vector<GetStatus> res(statuses.size());
values->resize(statuses.size());
for (size_t i = 0; i < statuses.size(); i++) {
auto &status = statuses[i];
if (status.ok()) {
res[i] = GetStatus::Ok;
values->at(i) = values_rocksdb[i].ToString();
} else if (status.code() == rocksdb::Status::kNotFound) {
res[i] = GetStatus::NotFound;
values->at(i) = "";
} else {
return from_rocksdb(status);
}
}
return res;
}
Status RocksDb::set(Slice key, Slice value) {
if (write_batch_) {
return from_rocksdb(write_batch_->Put(to_rocksdb(key), to_rocksdb(value)));

View file

@ -72,6 +72,7 @@ class RocksDb : public KeyValue {
static Result<RocksDb> open(std::string path, RocksDbOptions options = {});
Result<GetStatus> get(Slice key, std::string &value) override;
Result<std::vector<RocksDb::GetStatus>> get_multi(td::Span<Slice> keys, std::vector<std::string> *values) override;
Status set(Slice key, Slice value) override;
Status erase(Slice key) override;
Result<size_t> count(Slice prefix) override;