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:
parent
3c245c6146
commit
fbb9954391
14 changed files with 448 additions and 122 deletions
|
|
@ -166,6 +166,28 @@ td::Result<CellLoader::LoadResult> CellLoader::load(td::Slice hash, bool need_da
|
|||
return res;
|
||||
}
|
||||
|
||||
td::Result<std::vector<CellLoader::LoadResult>> CellLoader::load_bulk(td::Span<td::Slice> hashes, bool need_data,
|
||||
ExtCellCreator &ext_cell_creator) {
|
||||
std::vector<std::string> values;
|
||||
TRY_RESULT(get_statuses, reader_->get_multi(hashes, &values));
|
||||
std::vector<LoadResult> res;
|
||||
res.reserve(hashes.size());
|
||||
for (size_t i = 0; i < hashes.size(); i++) {
|
||||
auto get_status = get_statuses[i];
|
||||
if (get_status != KeyValue::GetStatus::Ok) {
|
||||
DCHECK(get_status == KeyValue::GetStatus::NotFound);
|
||||
res.push_back(LoadResult{});
|
||||
continue;
|
||||
}
|
||||
TRY_RESULT(load_res, load(hashes[i], values[i], need_data, ext_cell_creator));
|
||||
if (on_load_callback_) {
|
||||
on_load_callback_(load_res);
|
||||
}
|
||||
res.push_back(std::move(load_res));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
td::Result<CellLoader::LoadResult> CellLoader::load(td::Slice hash, td::Slice value, bool need_data,
|
||||
ExtCellCreator &ext_cell_creator) {
|
||||
LoadResult res;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ class CellLoader {
|
|||
};
|
||||
CellLoader(std::shared_ptr<KeyValueReader> reader, std::function<void(const LoadResult &)> on_load_callback = {});
|
||||
td::Result<LoadResult> load(td::Slice hash, bool need_data, ExtCellCreator &ext_cell_creator);
|
||||
td::Result<std::vector<LoadResult>> load_bulk(td::Span<td::Slice> hashes, bool need_data, ExtCellCreator &ext_cell_creator);
|
||||
static td::Result<LoadResult> load(td::Slice hash, td::Slice value, bool need_data, ExtCellCreator &ext_cell_creator);
|
||||
td::Result<LoadResult> load_refcnt(td::Slice hash); // This only loads refcnt_, cell_ == null
|
||||
|
||||
|
|
|
|||
|
|
@ -100,22 +100,15 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
return get_cell_info_lazy(level_mask, hash, depth).cell;
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_cell(td::Slice hash) override {
|
||||
auto info = hash_table_.get_if_exists(hash);
|
||||
if (info && info->sync_with_db) {
|
||||
TRY_RESULT(loaded_cell, info->cell->load_cell());
|
||||
return std::move(loaded_cell.data_cell);
|
||||
}
|
||||
TRY_RESULT(res, loader_->load(hash, true, *this));
|
||||
if (res.status != CellLoader::LoadResult::Ok) {
|
||||
return td::Status::Error("cell not found");
|
||||
}
|
||||
Ref<DataCell> cell = res.cell();
|
||||
hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_loaded(info, hash, std::move(res)); });
|
||||
return cell;
|
||||
TRY_RESULT(loaded_cell, get_cell_info_force(hash).cell->load_cell());
|
||||
return std::move(loaded_cell.data_cell);
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_root(td::Slice hash) override {
|
||||
return load_cell(hash);
|
||||
}
|
||||
td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<td::Slice> hashes) override {
|
||||
return td::Status::Error("Not implemented");
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_root_thread_safe(td::Slice hash) const override {
|
||||
return td::Status::Error("Not implemented");
|
||||
}
|
||||
|
|
@ -155,6 +148,9 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
promise->set_result(std::move(cell));
|
||||
});
|
||||
}
|
||||
CellInfo &get_cell_info_force(td::Slice hash) {
|
||||
return hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_force(info, hash); });
|
||||
}
|
||||
CellInfo &get_cell_info_lazy(Cell::LevelMask level_mask, td::Slice hash, td::Slice depth) {
|
||||
return hash_table_.apply(hash.substr(hash.size() - Cell::hash_bytes),
|
||||
[&](CellInfo &info) { update_cell_info_lazy(info, level_mask, hash, depth); });
|
||||
|
|
@ -334,6 +330,23 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
return std::move(load_result.cell());
|
||||
}
|
||||
|
||||
td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<td::Slice> hashes) override {
|
||||
if (db_) {
|
||||
return db_->load_bulk(hashes);
|
||||
}
|
||||
TRY_RESULT(load_result, cell_loader_->load_bulk(hashes, true, *this));
|
||||
|
||||
std::vector<Ref<DataCell>> res;
|
||||
res.reserve(load_result.size());
|
||||
for (auto &load_res : load_result) {
|
||||
if (load_res.status != CellLoader::LoadResult::Ok) {
|
||||
return td::Status::Error("cell not found");
|
||||
}
|
||||
res.push_back(std::move(load_res.cell()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
static td::NamedThreadSafeCounter::CounterRef get_thread_safe_counter() {
|
||||
static auto res = td::NamedThreadSafeCounter::get_default().get_counter("DynamicBagOfCellsDbLoader");
|
||||
|
|
|
|||
|
|
@ -44,12 +44,14 @@ class CellDbReader {
|
|||
public:
|
||||
virtual ~CellDbReader() = default;
|
||||
virtual td::Result<Ref<DataCell>> load_cell(td::Slice hash) = 0;
|
||||
virtual td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<td::Slice> hashes) = 0;
|
||||
};
|
||||
|
||||
class DynamicBagOfCellsDb {
|
||||
public:
|
||||
virtual ~DynamicBagOfCellsDb() = default;
|
||||
virtual td::Result<Ref<DataCell>> load_cell(td::Slice hash) = 0;
|
||||
virtual td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<td::Slice> hashes) = 0;
|
||||
virtual td::Result<Ref<DataCell>> load_root(td::Slice hash) = 0;
|
||||
virtual td::Result<Ref<DataCell>> load_root_thread_safe(td::Slice hash) const = 0;
|
||||
struct Stats {
|
||||
|
|
|
|||
|
|
@ -461,6 +461,16 @@ class CellStorage {
|
|||
return td::Status::Error("not found");
|
||||
}
|
||||
|
||||
td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<CellHash> hashes) const {
|
||||
std::vector<Ref<DataCell>> res;
|
||||
res.reserve(hashes.size());
|
||||
for (auto &hash : hashes) {
|
||||
TRY_RESULT(cell, load_cell(hash));
|
||||
res.push_back(std::move(cell));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
td::Result<Ref<DataCell>> load_root_local(const CellHash &hash) const {
|
||||
auto lock = local_access_.lock();
|
||||
if (auto it = local_roots_.find(hash); it != local_roots_.end()) {
|
||||
|
|
@ -769,6 +779,9 @@ class InMemoryBagOfCellsDb : public DynamicBagOfCellsDb {
|
|||
td::Result<Ref<DataCell>> load_root(td::Slice hash) override {
|
||||
return storage_->load_root_local(CellHash::from_slice(hash));
|
||||
}
|
||||
td::Result<std::vector<Ref<DataCell>>> load_bulk(td::Span<td::Slice> hashes) override {
|
||||
return storage_->load_bulk(td::transform(hashes, [](auto &hash) { return CellHash::from_slice(hash); }));
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_root_thread_safe(td::Slice hash) const override {
|
||||
return storage_->load_root_shared(CellHash::from_slice(hash));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue