mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
lru map for indexes
This commit is contained in:
@@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
// FIXME: Need to clean up ledgers by index at some point
|
|
||||||
|
|
||||||
LedgerHistory::LedgerHistory(
|
LedgerHistory::LedgerHistory(
|
||||||
beast::insight::Collector::ptr const& collector,
|
beast::insight::Collector::ptr const& collector,
|
||||||
Application& app)
|
Application& app)
|
||||||
@@ -47,6 +45,7 @@ LedgerHistory::LedgerHistory(
|
|||||||
std::chrono::minutes{5},
|
std::chrono::minutes{5},
|
||||||
stopwatch(),
|
stopwatch(),
|
||||||
app_.journal("TaggedCache"))
|
app_.journal("TaggedCache"))
|
||||||
|
, mLedgersByIndex(256)
|
||||||
, j_(app.journal("LedgerHistory"))
|
, j_(app.journal("LedgerHistory"))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -68,7 +67,13 @@ LedgerHistory::insert(
|
|||||||
bool const alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(
|
bool const alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(
|
||||||
ledger->info().hash, ledger);
|
ledger->info().hash, ledger);
|
||||||
if (validated)
|
if (validated)
|
||||||
|
{
|
||||||
mLedgersByIndex[ledger->info().seq] = ledger->info().hash;
|
mLedgersByIndex[ledger->info().seq] = ledger->info().hash;
|
||||||
|
JLOG(j_.info()) << "LedgerHistory::insert: mLedgersByIndex size: "
|
||||||
|
<< mLedgersByIndex.size() << " , total size: "
|
||||||
|
<< mLedgersByIndex.size() *
|
||||||
|
(sizeof(LedgerIndex) + sizeof(LedgerHash));
|
||||||
|
}
|
||||||
|
|
||||||
return alreadyHad;
|
return alreadyHad;
|
||||||
}
|
}
|
||||||
@@ -115,6 +120,11 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
|||||||
"ripple::LedgerHistory::getLedgerBySeq : immutable result ledger");
|
"ripple::LedgerHistory::getLedgerBySeq : immutable result ledger");
|
||||||
m_ledgers_by_hash.canonicalize_replace_client(ret->info().hash, ret);
|
m_ledgers_by_hash.canonicalize_replace_client(ret->info().hash, ret);
|
||||||
mLedgersByIndex[ret->info().seq] = ret->info().hash;
|
mLedgersByIndex[ret->info().seq] = ret->info().hash;
|
||||||
|
JLOG(j_.info())
|
||||||
|
<< "LedgerHistory::getLedgerBySeq: mLedgersByIndex size: "
|
||||||
|
<< mLedgersByIndex.size() << " , total size: "
|
||||||
|
<< mLedgersByIndex.size() *
|
||||||
|
(sizeof(LedgerIndex) + sizeof(LedgerHash));
|
||||||
return (ret->info().seq == index) ? ret : nullptr;
|
return (ret->info().seq == index) ? ret : nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <xrpld/app/ledger/Ledger.h>
|
#include <xrpld/app/ledger/Ledger.h>
|
||||||
#include <xrpld/app/main/Application.h>
|
#include <xrpld/app/main/Application.h>
|
||||||
|
#include <xrpld/core/detail/LRUMap.h>
|
||||||
|
|
||||||
#include <xrpl/beast/insight/Collector.h>
|
#include <xrpl/beast/insight/Collector.h>
|
||||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||||
@@ -149,7 +150,7 @@ private:
|
|||||||
ConsensusValidated m_consensus_validated;
|
ConsensusValidated m_consensus_validated;
|
||||||
|
|
||||||
// Maps ledger indexes to the corresponding hash.
|
// Maps ledger indexes to the corresponding hash.
|
||||||
std::map<LedgerIndex, LedgerHash> mLedgersByIndex; // validated ledgers
|
LRUMap<LedgerIndex, LedgerHash> mLedgersByIndex; // validated ledgers
|
||||||
|
|
||||||
beast::Journal j_;
|
beast::Journal j_;
|
||||||
};
|
};
|
||||||
|
|||||||
147
src/xrpld/core/detail/LRUMap.h
Normal file
147
src/xrpld/core/detail/LRUMap.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_APP_LRU_MAP_H_INCLUDED
|
||||||
|
#define RIPPLE_APP_LRU_MAP_H_INCLUDED
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
template <typename Key, typename Value>
|
||||||
|
class LRUMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit LRUMap(std::size_t capacity) : capacity_(capacity)
|
||||||
|
{
|
||||||
|
// TODO: check capacity_ > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Value&
|
||||||
|
operator[](Key const& key)
|
||||||
|
{
|
||||||
|
auto it = data_.find(key);
|
||||||
|
if (it != data_.end())
|
||||||
|
{
|
||||||
|
bump_to_front(key);
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
if (data_.size() >= capacity_)
|
||||||
|
{
|
||||||
|
Key const& lru = usage_list_.back();
|
||||||
|
usage_list_.pop_back();
|
||||||
|
data_.erase(lru);
|
||||||
|
}
|
||||||
|
usage_list_.push_front(key);
|
||||||
|
return data_[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto
|
||||||
|
find(Key const& key)
|
||||||
|
{
|
||||||
|
return data_.find(key);
|
||||||
|
}
|
||||||
|
auto
|
||||||
|
find(Key const& key) const
|
||||||
|
{
|
||||||
|
return data_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto
|
||||||
|
begin()
|
||||||
|
{
|
||||||
|
return data_.begin();
|
||||||
|
}
|
||||||
|
auto
|
||||||
|
begin() const
|
||||||
|
{
|
||||||
|
return data_.begin();
|
||||||
|
}
|
||||||
|
auto
|
||||||
|
end()
|
||||||
|
{
|
||||||
|
return data_.end();
|
||||||
|
}
|
||||||
|
auto
|
||||||
|
end() const
|
||||||
|
{
|
||||||
|
return data_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
erase(Key const& key)
|
||||||
|
{
|
||||||
|
auto it = data_.find(key);
|
||||||
|
if (it == data_.end())
|
||||||
|
return false;
|
||||||
|
for (auto list_it = usage_list_.begin(); list_it != usage_list_.end();
|
||||||
|
++list_it)
|
||||||
|
{
|
||||||
|
if (*list_it == key)
|
||||||
|
{
|
||||||
|
usage_list_.erase(list_it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data_.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
size() const noexcept
|
||||||
|
{
|
||||||
|
return data_.size();
|
||||||
|
}
|
||||||
|
std::size_t
|
||||||
|
capacity() const noexcept
|
||||||
|
{
|
||||||
|
return capacity_;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
data_.clear();
|
||||||
|
usage_list_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void
|
||||||
|
bump_to_front(Key const& key)
|
||||||
|
{
|
||||||
|
for (auto it = usage_list_.begin(); it != usage_list_.end(); ++it)
|
||||||
|
{
|
||||||
|
if (*it == key)
|
||||||
|
{
|
||||||
|
usage_list_.erase(it);
|
||||||
|
usage_list_.push_front(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t capacity_;
|
||||||
|
std::map<Key, Value> data_;
|
||||||
|
std::list<Key> usage_list_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user