diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2018-05-16 22:41:50 +0100 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2018-05-21 19:51:58 +0100 |
commit | 5f8ffca34d87e46b7a44964e61733bfe5a85c028 (patch) | |
tree | 0236964fb6c1b7116e81ce9686e661d264a620d6 /src/blockchain_db | |
parent | Merge pull request #3830 (diff) | |
download | monero-5f8ffca34d87e46b7a44964e61733bfe5a85c028.tar.xz |
speed up get_output_distribution (and precalc common case)
Diffstat (limited to 'src/blockchain_db')
-rw-r--r-- | src/blockchain_db/blockchain_db.h | 2 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 41 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 2 |
3 files changed, 45 insertions, 0 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 1a23a9ada..1ed715315 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1496,6 +1496,8 @@ public: */ virtual std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const = 0; + virtual bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const = 0; + /** * @brief is BlockchainDB in read-only mode? * diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 5672a34f6..5c20c8de4 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -3179,6 +3179,47 @@ std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> BlockchainLMDB::get return histogram; } +bool BlockchainLMDB::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(output_amounts); + + distribution.clear(); + const uint64_t db_height = height(); + if (from_height >= db_height) + return false; + distribution.resize(db_height - from_height, 0); + + bool fret = true; + MDB_val_set(k, amount); + MDB_val v; + MDB_cursor_op op = MDB_SET; + while (1) + { + int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op); + op = MDB_NEXT_DUP; + if (ret == MDB_NOTFOUND) + break; + if (ret) + throw0(DB_ERROR("Failed to enumerate outputs")); + const outkey *ok = (const outkey *)v.mv_data; + const uint64_t height = ok->data.height; + if (height >= from_height) + distribution[height - from_height]++; + else + base++; + if (to_height > 0 && height > to_height) + break; + } + + TXN_POSTFIX_RDONLY(); + + return true; +} + void BlockchainLMDB::check_hard_fork_info() { } diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 9a20c0f1e..f1773bac8 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -293,6 +293,8 @@ public: */ std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const; + bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const; + private: void do_resize(uint64_t size_increase=0); |