diff --git a/Builds/CMake/RippledCore.cmake b/Builds/CMake/RippledCore.cmake index 6fc33cdee..43df0959a 100644 --- a/Builds/CMake/RippledCore.cmake +++ b/Builds/CMake/RippledCore.cmake @@ -548,7 +548,6 @@ target_sources (rippled PRIVATE src/ripple/nodestore/backend/CassandraFactory.cpp src/ripple/nodestore/backend/RWDBFactory.cpp src/ripple/nodestore/backend/MemoryFactory.cpp - src/ripple/nodestore/backend/FlatmapFactory.cpp src/ripple/nodestore/backend/NuDBFactory.cpp src/ripple/nodestore/backend/NullFactory.cpp src/ripple/nodestore/backend/RocksDBFactory.cpp diff --git a/src/ripple/app/rdb/backend/FlatmapDatabase.h b/src/ripple/app/rdb/backend/FlatmapDatabase.h deleted file mode 100644 index 00927b1d4..000000000 --- a/src/ripple/app/rdb/backend/FlatmapDatabase.h +++ /dev/null @@ -1,851 +0,0 @@ -#ifndef RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED -#define RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ripple { - -struct base_uint_hasher -{ - using result_type = std::size_t; - - result_type - operator()(base_uint<256> const& value) const - { - return hardened_hash<>{}(value); - } - - result_type - operator()(AccountID const& value) const - { - return hardened_hash<>{}(value); - } -}; - -class FlatmapDatabase : public SQLiteDatabase -{ -private: - struct LedgerData - { - LedgerInfo info; - boost::unordered:: - concurrent_flat_map - transactions; - }; - - struct AccountTxData - { - boost::unordered:: - concurrent_flat_map, AccountTx> - transactions; - }; - - Application& app_; - - boost::unordered::concurrent_flat_map ledgers_; - boost::unordered:: - concurrent_flat_map - ledgerHashToSeq_; - boost::unordered::concurrent_flat_map - transactionMap_; - boost::unordered:: - concurrent_flat_map - accountTxMap_; - -public: - FlatmapDatabase(Application& app, Config const& config, JobQueue& jobQueue) - : app_(app) - { - } - - std::optional - getMinLedgerSeq() override - { - std::optional minSeq; - ledgers_.visit_all([&minSeq](auto const& pair) { - if (!minSeq || pair.first < *minSeq) - { - minSeq = pair.first; - } - }); - return minSeq; - } - - std::optional - getTransactionsMinLedgerSeq() override - { - std::optional minSeq; - transactionMap_.visit_all([&minSeq](auto const& pair) { - LedgerIndex seq = pair.second.second->getLgrSeq(); - if (!minSeq || seq < *minSeq) - { - minSeq = seq; - } - }); - return minSeq; - } - - std::optional - getAccountTransactionsMinLedgerSeq() override - { - std::optional minSeq; - accountTxMap_.visit_all([&minSeq](auto const& pair) { - pair.second.transactions.visit_all([&minSeq](auto const& tx) { - if (!minSeq || tx.first.first < *minSeq) - { - minSeq = tx.first.first; - } - }); - }); - return minSeq; - } - - std::optional - getMaxLedgerSeq() override - { - std::optional maxSeq; - ledgers_.visit_all([&maxSeq](auto const& pair) { - if (!maxSeq || pair.first > *maxSeq) - { - maxSeq = pair.first; - } - }); - return maxSeq; - } - void - deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) override - { - ledgers_.visit(ledgerSeq, [this](auto& item) { - item.second.transactions.visit_all([this](auto const& txPair) { - transactionMap_.erase(txPair.first); - }); - item.second.transactions.clear(); - }); - - accountTxMap_.visit_all([ledgerSeq](auto& item) { - item.second.transactions.erase_if([ledgerSeq](auto const& tx) { - return tx.first.first == ledgerSeq; - }); - }); - } - - void - deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) override - { - ledgers_.erase_if([this, ledgerSeq](auto const& item) { - if (item.first < ledgerSeq) - { - item.second.transactions.visit_all([this](auto const& txPair) { - transactionMap_.erase(txPair.first); - }); - ledgerHashToSeq_.erase(item.second.info.hash); - return true; - } - return false; - }); - - accountTxMap_.visit_all([ledgerSeq](auto& item) { - item.second.transactions.erase_if([ledgerSeq](auto const& tx) { - return tx.first.first < ledgerSeq; - }); - }); - } - - void - deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override - { - ledgers_.visit_all([this, ledgerSeq](auto& item) { - if (item.first < ledgerSeq) - { - item.second.transactions.visit_all([this](auto const& txPair) { - transactionMap_.erase(txPair.first); - }); - item.second.transactions.clear(); - } - }); - - accountTxMap_.visit_all([ledgerSeq](auto& item) { - item.second.transactions.erase_if([ledgerSeq](auto const& tx) { - return tx.first.first < ledgerSeq; - }); - }); - } - - void - deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override - { - accountTxMap_.visit_all([ledgerSeq](auto& item) { - item.second.transactions.erase_if([ledgerSeq](auto const& tx) { - return tx.first.first < ledgerSeq; - }); - }); - } - std::size_t - getTransactionCount() override - { - return transactionMap_.size(); - } - - std::size_t - getAccountTransactionCount() override - { - std::size_t count = 0; - accountTxMap_.visit_all([&count](auto const& item) { - count += item.second.transactions.size(); - }); - return count; - } - - CountMinMax - getLedgerCountMinMax() override - { - CountMinMax result{0, 0, 0}; - ledgers_.visit_all([&result](auto const& item) { - result.numberOfRows++; - if (result.minLedgerSequence == 0 || - item.first < result.minLedgerSequence) - { - result.minLedgerSequence = item.first; - } - if (item.first > result.maxLedgerSequence) - { - result.maxLedgerSequence = item.first; - } - }); - return result; - } - - bool - saveValidatedLedger( - std::shared_ptr const& ledger, - bool current) override - { - try - { - LedgerData ledgerData; - ledgerData.info = ledger->info(); - - auto aLedger = std::make_shared(ledger, app_); - for (auto const& acceptedLedgerTx : *aLedger) - { - auto const& txn = acceptedLedgerTx->getTxn(); - auto const& meta = acceptedLedgerTx->getMeta(); - auto const& id = txn->getTransactionID(); - - std::string reason; - auto accTx = std::make_pair( - std::make_shared(txn, reason, app_), - std::make_shared(meta)); - - ledgerData.transactions.emplace(id, accTx); - transactionMap_.emplace(id, accTx); - - for (auto const& account : meta.getAffectedAccounts()) - { - accountTxMap_.visit(account, [&](auto& data) { - data.second.transactions.emplace( - std::make_pair( - ledger->info().seq, - acceptedLedgerTx->getTxnSeq()), - accTx); - }); - } - } - - ledgers_.emplace(ledger->info().seq, std::move(ledgerData)); - ledgerHashToSeq_.emplace(ledger->info().hash, ledger->info().seq); - - if (current) - { - auto const cutoffSeq = - ledger->info().seq > app_.config().LEDGER_HISTORY - ? ledger->info().seq - app_.config().LEDGER_HISTORY - : 0; - - if (cutoffSeq > 0) - { - const std::size_t BATCH_SIZE = 128; - std::size_t deleted = 0; - - ledgers_.erase_if([&](auto const& item) { - if (deleted >= BATCH_SIZE) - return false; - - if (item.first < cutoffSeq) - { - item.second.transactions.visit_all( - [this](auto const& txPair) { - transactionMap_.erase(txPair.first); - }); - ledgerHashToSeq_.erase(item.second.info.hash); - deleted++; - return true; - } - return false; - }); - - if (deleted > 0) - { - accountTxMap_.visit_all([cutoffSeq](auto& item) { - item.second.transactions.erase_if( - [cutoffSeq](auto const& tx) { - return tx.first.first < cutoffSeq; - }); - }); - } - - app_.getLedgerMaster().clearPriorLedgers(cutoffSeq); - } - } - - return true; - } - catch (std::exception const&) - { - deleteTransactionByLedgerSeq(ledger->info().seq); - return false; - } - } - - std::optional - getLedgerInfoByIndex(LedgerIndex ledgerSeq) override - { - std::optional result; - ledgers_.visit(ledgerSeq, [&result](auto const& item) { - result = item.second.info; - }); - return result; - } - - std::optional - getNewestLedgerInfo() override - { - std::optional result; - ledgers_.visit_all([&result](auto const& item) { - if (!result || item.second.info.seq > result->seq) - { - result = item.second.info; - } - }); - return result; - } - - std::optional - getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override - { - std::optional result; - ledgers_.visit_all([&](auto const& item) { - if (item.first >= ledgerFirstIndex && - (!result || item.first < result->seq)) - { - result = item.second.info; - } - }); - return result; - } - - std::optional - getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override - { - std::optional result; - ledgers_.visit_all([&](auto const& item) { - if (item.first >= ledgerFirstIndex && - (!result || item.first > result->seq)) - { - result = item.second.info; - } - }); - return result; - } - - std::optional - getLedgerInfoByHash(uint256 const& ledgerHash) override - { - std::optional result; - ledgerHashToSeq_.visit(ledgerHash, [this, &result](auto const& item) { - ledgers_.visit(item.second, [&result](auto const& item) { - result = item.second.info; - }); - }); - return result; - } - uint256 - getHashByIndex(LedgerIndex ledgerIndex) override - { - uint256 result; - ledgers_.visit(ledgerIndex, [&result](auto const& item) { - result = item.second.info.hash; - }); - return result; - } - - std::optional - getHashesByIndex(LedgerIndex ledgerIndex) override - { - std::optional result; - ledgers_.visit(ledgerIndex, [&result](auto const& item) { - result = LedgerHashPair{ - item.second.info.hash, item.second.info.parentHash}; - }); - return result; - } - - std::map - getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) override - { - std::map result; - ledgers_.visit_all([&](auto const& item) { - if (item.first >= minSeq && item.first <= maxSeq) - { - result[item.first] = LedgerHashPair{ - item.second.info.hash, item.second.info.parentHash}; - } - }); - return result; - } - - std::variant - getTransaction( - uint256 const& id, - std::optional> const& range, - error_code_i& ec) override - { - std::variant result = TxSearched::unknown; - transactionMap_.visit(id, [&](auto const& item) { - auto const& tx = item.second; - if (!range || - (range->lower() <= tx.second->getLgrSeq() && - tx.second->getLgrSeq() <= range->upper())) - { - result = tx; - } - else - { - result = TxSearched::all; - } - }); - return result; - } - - bool - ledgerDbHasSpace(Config const& config) override - { - return true; // In-memory database always has space - } - - bool - transactionDbHasSpace(Config const& config) override - { - return true; // In-memory database always has space - } - - std::uint32_t - getKBUsedAll() override - { - std::uint32_t size = sizeof(*this); - size += ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData)); - size += - ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex)); - size += transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx)); - accountTxMap_.visit_all([&size](auto const& item) { - size += sizeof(AccountID) + sizeof(AccountTxData); - size += item.second.transactions.size() * sizeof(AccountTx); - }); - return size / 1024; // Convert to KB - } - - std::uint32_t - getKBUsedLedger() override - { - std::uint32_t size = - ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData)); - size += - ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex)); - return size / 1024; - } - - std::uint32_t - getKBUsedTransaction() override - { - std::uint32_t size = - transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx)); - accountTxMap_.visit_all([&size](auto const& item) { - size += sizeof(AccountID) + sizeof(AccountTxData); - size += item.second.transactions.size() * sizeof(AccountTx); - }); - return size / 1024; - } - - void - closeLedgerDB() override - { - // No-op for in-memory database - } - - void - closeTransactionDB() override - { - // No-op for in-memory database - } - - ~FlatmapDatabase() - { - // Concurrent maps need visit_all - accountTxMap_.visit_all( - [](auto& pair) { pair.second.transactions.clear(); }); - accountTxMap_.clear(); - - transactionMap_.clear(); - - ledgers_.visit_all( - [](auto& pair) { pair.second.transactions.clear(); }); - ledgers_.clear(); - - ledgerHashToSeq_.clear(); - } - - std::vector> - getTxHistory(LedgerIndex startIndex) override - { - std::vector> result; - transactionMap_.visit_all([&](auto const& item) { - if (item.second.second->getLgrSeq() >= startIndex) - { - result.push_back(item.second.first); - } - }); - std::sort( - result.begin(), result.end(), [](auto const& a, auto const& b) { - return a->getLedger() > b->getLedger(); - }); - if (result.size() > 20) - { - result.resize(20); - } - return result; - } - // Helper function to handle limits - template - void - applyLimit(Container& container, std::size_t limit, bool bUnlimited) - { - if (!bUnlimited && limit > 0 && container.size() > limit) - { - container.resize(limit); - } - } - - AccountTxs - getOldestAccountTxs(AccountTxOptions const& options) override - { - AccountTxs result; - accountTxMap_.visit(options.account, [&](auto const& item) { - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - result.push_back(tx.second); - } - }); - }); - std::sort( - result.begin(), result.end(), [](auto const& a, auto const& b) { - return a.second->getLgrSeq() < b.second->getLgrSeq(); - }); - applyLimit(result, options.limit, options.bUnlimited); - return result; - } - - AccountTxs - getNewestAccountTxs(AccountTxOptions const& options) override - { - AccountTxs result; - accountTxMap_.visit(options.account, [&](auto const& item) { - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - result.push_back(tx.second); - } - }); - }); - std::sort( - result.begin(), result.end(), [](auto const& a, auto const& b) { - return a.second->getLgrSeq() > b.second->getLgrSeq(); - }); - applyLimit(result, options.limit, options.bUnlimited); - return result; - } - - MetaTxsList - getOldestAccountTxsB(AccountTxOptions const& options) override - { - MetaTxsList result; - accountTxMap_.visit(options.account, [&](auto const& item) { - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - result.emplace_back( - tx.second.first->getSTransaction() - ->getSerializer() - .peekData(), - tx.second.second->getAsObject() - .getSerializer() - .peekData(), - tx.first.first); - } - }); - }); - std::sort( - result.begin(), result.end(), [](auto const& a, auto const& b) { - return std::get<2>(a) < std::get<2>(b); - }); - applyLimit(result, options.limit, options.bUnlimited); - return result; - } - - MetaTxsList - getNewestAccountTxsB(AccountTxOptions const& options) override - { - MetaTxsList result; - accountTxMap_.visit(options.account, [&](auto const& item) { - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - result.emplace_back( - tx.second.first->getSTransaction() - ->getSerializer() - .peekData(), - tx.second.second->getAsObject() - .getSerializer() - .peekData(), - tx.first.first); - } - }); - }); - std::sort( - result.begin(), result.end(), [](auto const& a, auto const& b) { - return std::get<2>(a) > std::get<2>(b); - }); - applyLimit(result, options.limit, options.bUnlimited); - return result; - } - std::pair> - oldestAccountTxPage(AccountTxPageOptions const& options) override - { - AccountTxs result; - std::optional marker; - - accountTxMap_.visit(options.account, [&](auto const& item) { - std::vector, AccountTx>> - txs; - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - txs.emplace_back(tx); - } - }); - - std::sort(txs.begin(), txs.end(), [](auto const& a, auto const& b) { - return a.first < b.first; - }); - - auto it = txs.begin(); - if (options.marker) - { - it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) { - return tx.first.first == options.marker->ledgerSeq && - tx.first.second == options.marker->txnSeq; - }); - if (it != txs.end()) - ++it; - } - - for (; it != txs.end() && - (options.limit == 0 || result.size() < options.limit); - ++it) - { - result.push_back(it->second); - } - - if (it != txs.end()) - { - marker = AccountTxMarker{it->first.first, it->first.second}; - } - }); - - return {result, marker}; - } - - std::pair> - newestAccountTxPage(AccountTxPageOptions const& options) override - { - AccountTxs result; - std::optional marker; - - accountTxMap_.visit(options.account, [&](auto const& item) { - std::vector, AccountTx>> - txs; - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - txs.emplace_back(tx); - } - }); - - std::sort(txs.begin(), txs.end(), [](auto const& a, auto const& b) { - return a.first > b.first; - }); - - auto it = txs.begin(); - if (options.marker) - { - it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) { - return tx.first.first == options.marker->ledgerSeq && - tx.first.second == options.marker->txnSeq; - }); - if (it != txs.end()) - ++it; - } - - for (; it != txs.end() && - (options.limit == 0 || result.size() < options.limit); - ++it) - { - result.push_back(it->second); - } - - if (it != txs.end()) - { - marker = AccountTxMarker{it->first.first, it->first.second}; - } - }); - - return {result, marker}; - } - - std::pair> - oldestAccountTxPageB(AccountTxPageOptions const& options) override - { - MetaTxsList result; - std::optional marker; - - accountTxMap_.visit(options.account, [&](auto const& item) { - std::vector> txs; - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - txs.emplace_back( - tx.first.first, tx.first.second, tx.second); - } - }); - - std::sort(txs.begin(), txs.end()); - - auto it = txs.begin(); - if (options.marker) - { - it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) { - return std::get<0>(tx) == options.marker->ledgerSeq && - std::get<1>(tx) == options.marker->txnSeq; - }); - if (it != txs.end()) - ++it; - } - - for (; it != txs.end() && - (options.limit == 0 || result.size() < options.limit); - ++it) - { - const auto& [_, __, tx] = *it; - result.emplace_back( - tx.first->getSTransaction()->getSerializer().peekData(), - tx.second->getAsObject().getSerializer().peekData(), - std::get<0>(*it)); - } - - if (it != txs.end()) - { - marker = AccountTxMarker{std::get<0>(*it), std::get<1>(*it)}; - } - }); - - return {result, marker}; - } - - std::pair> - newestAccountTxPageB(AccountTxPageOptions const& options) override - { - MetaTxsList result; - std::optional marker; - - accountTxMap_.visit(options.account, [&](auto const& item) { - std::vector> txs; - item.second.transactions.visit_all([&](auto const& tx) { - if (tx.first.first >= options.minLedger && - tx.first.first <= options.maxLedger) - { - txs.emplace_back( - tx.first.first, tx.first.second, tx.second); - } - }); - - std::sort(txs.begin(), txs.end(), std::greater<>()); - - auto it = txs.begin(); - if (options.marker) - { - it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) { - return std::get<0>(tx) == options.marker->ledgerSeq && - std::get<1>(tx) == options.marker->txnSeq; - }); - if (it != txs.end()) - ++it; - } - - for (; it != txs.end() && - (options.limit == 0 || result.size() < options.limit); - ++it) - { - const auto& [_, __, tx] = *it; - result.emplace_back( - tx.first->getSTransaction()->getSerializer().peekData(), - tx.second->getAsObject().getSerializer().peekData(), - std::get<0>(*it)); - } - - if (it != txs.end()) - { - marker = AccountTxMarker{std::get<0>(*it), std::get<1>(*it)}; - } - }); - - return {result, marker}; - } -}; - -// Factory function -std::unique_ptr -getFlatmapDatabase(Application& app, Config const& config, JobQueue& jobQueue) -{ - return std::make_unique(app, config, jobQueue); -} - -} // namespace ripple -#endif // RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED diff --git a/src/ripple/app/rdb/impl/RelationalDatabase.cpp b/src/ripple/app/rdb/impl/RelationalDatabase.cpp index 64161bd53..bf24d7dc7 100644 --- a/src/ripple/app/rdb/impl/RelationalDatabase.cpp +++ b/src/ripple/app/rdb/impl/RelationalDatabase.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -41,7 +40,6 @@ RelationalDatabase::init( bool use_sqlite = false; bool use_postgres = false; bool use_rwdb = false; - bool use_flatmap = false; if (config.reporting()) { @@ -60,10 +58,6 @@ RelationalDatabase::init( { use_rwdb = true; } - else if (boost::iequals(get(rdb_section, "backend"), "flatmap")) - { - use_flatmap = true; - } else { Throw( @@ -89,10 +83,6 @@ RelationalDatabase::init( { return getRWDBDatabase(app, config, jobQueue); } - else if (use_flatmap) - { - return getFlatmapDatabase(app, config, jobQueue); - } return std::unique_ptr(); } diff --git a/src/ripple/core/Config.h b/src/ripple/core/Config.h index 3e2c3c81a..99af17272 100644 --- a/src/ripple/core/Config.h +++ b/src/ripple/core/Config.h @@ -363,7 +363,7 @@ public: (!section("node_db").empty() && (boost::beast::iequals(get(section("node_db"), "type"), "rwdb") || boost::beast::iequals( - get(section("node_db"), "type"), "flatmap"))); + get(section("node_db"), "type"), "memory"))); // RHNOTE: memory type is not selected for here because it breaks // tests return isMem; diff --git a/src/ripple/nodestore/backend/FlatmapFactory.cpp b/src/ripple/nodestore/backend/FlatmapFactory.cpp deleted file mode 100644 index 4cec115ef..000000000 --- a/src/ripple/nodestore/backend/FlatmapFactory.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ripple { -namespace NodeStore { - -class FlatmapBackend : public Backend -{ -private: - std::string name_; - beast::Journal journal_; - bool isOpen_{false}; - - struct base_uint_hasher - { - using result_type = std::size_t; - - result_type - operator()(base_uint<256> const& value) const - { - return hardened_hash<>{}(value); - } - }; - - using DataStore = boost::unordered::concurrent_flat_map< - uint256, - std::vector, // Store compressed blob data - base_uint_hasher>; - - DataStore table_; - -public: - FlatmapBackend( - size_t keyBytes, - Section const& keyValues, - beast::Journal journal) - : name_(get(keyValues, "path")), journal_(journal) - { - boost::ignore_unused(journal_); - if (name_.empty()) - name_ = "node_db"; - } - - ~FlatmapBackend() override - { - close(); - } - - std::string - getName() override - { - return name_; - } - - void - open(bool createIfMissing) override - { - if (isOpen_) - Throw("already open"); - isOpen_ = true; - } - - bool - isOpen() override - { - return isOpen_; - } - - void - close() override - { - table_.clear(); - isOpen_ = false; - } - - Status - fetch(void const* key, std::shared_ptr* pObject) override - { - if (!isOpen_) - return notFound; - - uint256 const hash(uint256::fromVoid(key)); - - bool found = table_.visit(hash, [&](const auto& key_value_pair) { - nudb::detail::buffer bf; - auto const result = nodeobject_decompress( - key_value_pair.second.data(), key_value_pair.second.size(), bf); - DecodedBlob decoded(hash.data(), result.first, result.second); - if (!decoded.wasOk()) - { - *pObject = nullptr; - return; - } - *pObject = decoded.createObject(); - }); - return found ? (*pObject ? ok : dataCorrupt) : notFound; - } - - std::pair>, Status> - fetchBatch(std::vector const& hashes) override - { - std::vector> results; - results.reserve(hashes.size()); - for (auto const& h : hashes) - { - std::shared_ptr nObj; - Status status = fetch(h->begin(), &nObj); - if (status != ok) - results.push_back({}); - else - results.push_back(nObj); - } - return {results, ok}; - } - - void - store(std::shared_ptr const& object) override - { - if (!isOpen_) - return; - - if (!object) - return; - - EncodedBlob encoded(object); - nudb::detail::buffer bf; - auto const result = - nodeobject_compress(encoded.getData(), encoded.getSize(), bf); - - std::vector compressed( - static_cast(result.first), - static_cast(result.first) + result.second); - - table_.insert_or_assign(object->getHash(), std::move(compressed)); - } - - void - storeBatch(Batch const& batch) override - { - for (auto const& e : batch) - store(e); - } - - void - sync() override - { - } - - void - for_each(std::function)> f) override - { - if (!isOpen_) - return; - - table_.visit_all([&f](const auto& entry) { - nudb::detail::buffer bf; - auto const result = nodeobject_decompress( - entry.second.data(), entry.second.size(), bf); - DecodedBlob decoded( - entry.first.data(), result.first, result.second); - if (decoded.wasOk()) - f(decoded.createObject()); - }); - } - - int - getWriteLoad() override - { - return 0; - } - - void - setDeletePath() override - { - close(); - } - - int - fdRequired() const override - { - return 0; - } - -private: - size_t - size() const - { - return table_.size(); - } -}; - -class FlatmapFactory : public Factory -{ -public: - FlatmapFactory() - { - Manager::instance().insert(*this); - } - - ~FlatmapFactory() override - { - Manager::instance().erase(*this); - } - - std::string - getName() const override - { - return "Flatmap"; - } - - std::unique_ptr - createInstance( - size_t keyBytes, - Section const& keyValues, - std::size_t burstSize, - Scheduler& scheduler, - beast::Journal journal) override - { - return std::make_unique(keyBytes, keyValues, journal); - } -}; - -static FlatmapFactory flatmapFactory; - -} // namespace NodeStore -} // namespace ripple