mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-09 21:55:50 +00:00
Compare commits
5 Commits
a1q123456/
...
2.6.1-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d01f35eb9 | ||
|
|
1020a32d76 | ||
|
|
2df7dcfdeb | ||
|
|
c5fe970646 | ||
|
|
c57cd8b23e |
@@ -26,6 +26,9 @@ tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
|||||||
{% if compiler == "apple-clang" and compiler_version >= 17 %}
|
{% if compiler == "apple-clang" and compiler_version >= 17 %}
|
||||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if compiler == "clang" and compiler_version == 16 %}
|
||||||
|
tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
|
||||||
|
{% endif %}
|
||||||
{% if compiler == "gcc" and compiler_version < 13 %}
|
{% if compiler == "gcc" and compiler_version < 13 %}
|
||||||
tools.build:cxxflags=['-Wno-restrict']
|
tools.build:cxxflags=['-Wno-restrict']
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class Xrpl(ConanFile):
|
|||||||
def requirements(self):
|
def requirements(self):
|
||||||
# Conan 2 requires transitive headers to be specified
|
# Conan 2 requires transitive headers to be specified
|
||||||
transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {}
|
transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {}
|
||||||
self.requires('boost/1.86.0', force=True, **transitive_headers_opt)
|
self.requires('boost/1.83.0', force=True, **transitive_headers_opt)
|
||||||
self.requires('date/3.0.4', **transitive_headers_opt)
|
self.requires('date/3.0.4', **transitive_headers_opt)
|
||||||
self.requires('lz4/1.10.0', force=True)
|
self.requires('lz4/1.10.0', force=True)
|
||||||
self.requires('protobuf/3.21.12', force=True)
|
self.requires('protobuf/3.21.12', force=True)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define RIPPLE_BASICS_SHAMAP_HASH_H_INCLUDED
|
#define RIPPLE_BASICS_SHAMAP_HASH_H_INCLUDED
|
||||||
|
|
||||||
#include <xrpl/basics/base_uint.h>
|
#include <xrpl/basics/base_uint.h>
|
||||||
|
#include <xrpl/basics/partitioned_unordered_map.h>
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ public:
|
|||||||
int
|
int
|
||||||
getCacheSize() const;
|
getCacheSize() const;
|
||||||
|
|
||||||
|
int
|
||||||
|
getTrackSize() const;
|
||||||
|
|
||||||
float
|
float
|
||||||
getHitRate();
|
getHitRate();
|
||||||
|
|
||||||
@@ -167,6 +170,9 @@ public:
|
|||||||
bool
|
bool
|
||||||
retrieve(key_type const& key, T& data);
|
retrieve(key_type const& key, T& data);
|
||||||
|
|
||||||
|
mutex_type&
|
||||||
|
peekMutex();
|
||||||
|
|
||||||
std::vector<key_type>
|
std::vector<key_type>
|
||||||
getKeys() const;
|
getKeys() const;
|
||||||
|
|
||||||
@@ -187,14 +193,11 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
SharedPointerType
|
SharedPointerType
|
||||||
initialFetch(key_type const& key);
|
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l);
|
||||||
|
|
||||||
void
|
void
|
||||||
collect_metrics();
|
collect_metrics();
|
||||||
|
|
||||||
Mutex&
|
|
||||||
lockPartition(key_type const& key) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Stats
|
struct Stats
|
||||||
{
|
{
|
||||||
@@ -297,8 +300,8 @@ private:
|
|||||||
[[maybe_unused]] clock_type::time_point const& now,
|
[[maybe_unused]] clock_type::time_point const& now,
|
||||||
typename KeyValueCacheType::map_type& partition,
|
typename KeyValueCacheType::map_type& partition,
|
||||||
SweptPointersVector& stuffToSweep,
|
SweptPointersVector& stuffToSweep,
|
||||||
std::atomic<int>& allRemoval,
|
std::atomic<int>& allRemovals,
|
||||||
Mutex& partitionLock);
|
std::lock_guard<std::recursive_mutex> const&);
|
||||||
|
|
||||||
[[nodiscard]] std::thread
|
[[nodiscard]] std::thread
|
||||||
sweepHelper(
|
sweepHelper(
|
||||||
@@ -307,12 +310,14 @@ private:
|
|||||||
typename KeyOnlyCacheType::map_type& partition,
|
typename KeyOnlyCacheType::map_type& partition,
|
||||||
SweptPointersVector&,
|
SweptPointersVector&,
|
||||||
std::atomic<int>& allRemovals,
|
std::atomic<int>& allRemovals,
|
||||||
Mutex& partitionLock);
|
std::lock_guard<std::recursive_mutex> const&);
|
||||||
|
|
||||||
beast::Journal m_journal;
|
beast::Journal m_journal;
|
||||||
clock_type& m_clock;
|
clock_type& m_clock;
|
||||||
Stats m_stats;
|
Stats m_stats;
|
||||||
|
|
||||||
|
mutex_type mutable m_mutex;
|
||||||
|
|
||||||
// Used for logging
|
// Used for logging
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
@@ -323,11 +328,10 @@ private:
|
|||||||
clock_type::duration const m_target_age;
|
clock_type::duration const m_target_age;
|
||||||
|
|
||||||
// Number of items cached
|
// Number of items cached
|
||||||
std::atomic<int> m_cache_count;
|
int m_cache_count;
|
||||||
cache_type m_cache; // Hold strong reference to recent objects
|
cache_type m_cache; // Hold strong reference to recent objects
|
||||||
std::atomic<std::uint64_t> m_hits;
|
std::uint64_t m_hits;
|
||||||
std::atomic<std::uint64_t> m_misses;
|
std::uint64_t m_misses;
|
||||||
mutable std::vector<mutex_type> partitionLocks_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <xrpl/basics/IntrusivePointer.ipp>
|
#include <xrpl/basics/IntrusivePointer.ipp>
|
||||||
#include <xrpl/basics/TaggedCache.h>
|
#include <xrpl/basics/TaggedCache.h>
|
||||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ inline TaggedCache<
|
|||||||
, m_hits(0)
|
, m_hits(0)
|
||||||
, m_misses(0)
|
, m_misses(0)
|
||||||
{
|
{
|
||||||
partitionLocks_ = std::vector<mutex_type>(m_cache.partitions());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -107,13 +105,8 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::size() const
|
Mutex>::size() const
|
||||||
{
|
{
|
||||||
std::size_t totalSize = 0;
|
std::lock_guard lock(m_mutex);
|
||||||
for (size_t i = 0; i < partitionLocks_.size(); ++i)
|
return m_cache.size();
|
||||||
{
|
|
||||||
std::lock_guard<Mutex> lock(partitionLocks_[i]);
|
|
||||||
totalSize += m_cache.map()[i].size();
|
|
||||||
}
|
|
||||||
return totalSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -136,7 +129,32 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::getCacheSize() const
|
Mutex>::getCacheSize() const
|
||||||
{
|
{
|
||||||
return m_cache_count.load(std::memory_order_relaxed);
|
std::lock_guard lock(m_mutex);
|
||||||
|
return m_cache_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Key,
|
||||||
|
class T,
|
||||||
|
bool IsKeyCache,
|
||||||
|
class SharedWeakUnionPointer,
|
||||||
|
class SharedPointerType,
|
||||||
|
class Hash,
|
||||||
|
class KeyEqual,
|
||||||
|
class Mutex>
|
||||||
|
inline int
|
||||||
|
TaggedCache<
|
||||||
|
Key,
|
||||||
|
T,
|
||||||
|
IsKeyCache,
|
||||||
|
SharedWeakUnionPointer,
|
||||||
|
SharedPointerType,
|
||||||
|
Hash,
|
||||||
|
KeyEqual,
|
||||||
|
Mutex>::getTrackSize() const
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
|
return m_cache.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -159,10 +177,9 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::getHitRate()
|
Mutex>::getHitRate()
|
||||||
{
|
{
|
||||||
auto const hits = m_hits.load(std::memory_order_relaxed);
|
std::lock_guard lock(m_mutex);
|
||||||
auto const misses = m_misses.load(std::memory_order_relaxed);
|
auto const total = static_cast<float>(m_hits + m_misses);
|
||||||
float const total = float(hits + misses);
|
return m_hits * (100.0f / std::max(1.0f, total));
|
||||||
return hits * (100.0f / std::max(1.0f, total));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -185,12 +202,9 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::clear()
|
Mutex>::clear()
|
||||||
{
|
{
|
||||||
for (auto& mutex : partitionLocks_)
|
std::lock_guard lock(m_mutex);
|
||||||
mutex.lock();
|
|
||||||
m_cache.clear();
|
m_cache.clear();
|
||||||
for (auto& mutex : partitionLocks_)
|
m_cache_count = 0;
|
||||||
mutex.unlock();
|
|
||||||
m_cache_count.store(0, std::memory_order_relaxed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -213,9 +227,11 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::reset()
|
Mutex>::reset()
|
||||||
{
|
{
|
||||||
clear();
|
std::lock_guard lock(m_mutex);
|
||||||
m_hits.store(0, std::memory_order_relaxed);
|
m_cache.clear();
|
||||||
m_misses.store(0, std::memory_order_relaxed);
|
m_cache_count = 0;
|
||||||
|
m_hits = 0;
|
||||||
|
m_misses = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -239,7 +255,7 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::touch_if_exists(KeyComparable const& key)
|
Mutex>::touch_if_exists(KeyComparable const& key)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
std::lock_guard lock(m_mutex);
|
||||||
auto const iter(m_cache.find(key));
|
auto const iter(m_cache.find(key));
|
||||||
if (iter == m_cache.end())
|
if (iter == m_cache.end())
|
||||||
{
|
{
|
||||||
@@ -281,6 +297,8 @@ TaggedCache<
|
|||||||
|
|
||||||
auto const start = std::chrono::steady_clock::now();
|
auto const start = std::chrono::steady_clock::now();
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
|
|
||||||
if (m_target_size == 0 ||
|
if (m_target_size == 0 ||
|
||||||
(static_cast<int>(m_cache.size()) <= m_target_size))
|
(static_cast<int>(m_cache.size()) <= m_target_size))
|
||||||
{
|
{
|
||||||
@@ -312,13 +330,12 @@ TaggedCache<
|
|||||||
m_cache.map()[p],
|
m_cache.map()[p],
|
||||||
allStuffToSweep[p],
|
allStuffToSweep[p],
|
||||||
allRemovals,
|
allRemovals,
|
||||||
partitionLocks_[p]));
|
lock));
|
||||||
}
|
}
|
||||||
for (std::thread& worker : workers)
|
for (std::thread& worker : workers)
|
||||||
worker.join();
|
worker.join();
|
||||||
|
|
||||||
int removals = allRemovals.load(std::memory_order_relaxed);
|
m_cache_count -= allRemovals;
|
||||||
m_cache_count.fetch_sub(removals, std::memory_order_relaxed);
|
|
||||||
}
|
}
|
||||||
// At this point allStuffToSweep will go out of scope outside the lock
|
// At this point allStuffToSweep will go out of scope outside the lock
|
||||||
// and decrement the reference count on each strong pointer.
|
// and decrement the reference count on each strong pointer.
|
||||||
@@ -352,8 +369,7 @@ TaggedCache<
|
|||||||
{
|
{
|
||||||
// Remove from cache, if !valid, remove from map too. Returns true if
|
// Remove from cache, if !valid, remove from map too. Returns true if
|
||||||
// removed from cache
|
// removed from cache
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
|
||||||
|
|
||||||
auto cit = m_cache.find(key);
|
auto cit = m_cache.find(key);
|
||||||
|
|
||||||
@@ -366,7 +382,7 @@ TaggedCache<
|
|||||||
|
|
||||||
if (entry.isCached())
|
if (entry.isCached())
|
||||||
{
|
{
|
||||||
m_cache_count.fetch_sub(1, std::memory_order_relaxed);
|
--m_cache_count;
|
||||||
entry.ptr.convertToWeak();
|
entry.ptr.convertToWeak();
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
@@ -404,16 +420,17 @@ TaggedCache<
|
|||||||
{
|
{
|
||||||
// Return canonical value, store if needed, refresh in cache
|
// Return canonical value, store if needed, refresh in cache
|
||||||
// Return values: true=we had the data already
|
// Return values: true=we had the data already
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
|
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
|
||||||
auto cit = m_cache.find(key);
|
auto cit = m_cache.find(key);
|
||||||
|
|
||||||
if (cit == m_cache.end())
|
if (cit == m_cache.end())
|
||||||
{
|
{
|
||||||
m_cache.emplace(
|
m_cache.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::forward_as_tuple(key),
|
std::forward_as_tuple(key),
|
||||||
std::forward_as_tuple(m_clock.now(), data));
|
std::forward_as_tuple(m_clock.now(), data));
|
||||||
m_cache_count.fetch_add(1, std::memory_order_relaxed);
|
++m_cache_count;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,12 +479,12 @@ TaggedCache<
|
|||||||
data = cachedData;
|
data = cachedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cache_count.fetch_add(1, std::memory_order_relaxed);
|
++m_cache_count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.ptr = data;
|
entry.ptr = data;
|
||||||
m_cache_count.fetch_add(1, std::memory_order_relaxed);
|
++m_cache_count;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -543,11 +560,10 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::fetch(key_type const& key)
|
Mutex>::fetch(key_type const& key)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
std::lock_guard<mutex_type> l(m_mutex);
|
||||||
|
auto ret = initialFetch(key, l);
|
||||||
auto ret = initialFetch(key);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
m_misses.fetch_add(1, std::memory_order_relaxed);
|
++m_misses;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,8 +627,8 @@ TaggedCache<
|
|||||||
Mutex>::insert(key_type const& key)
|
Mutex>::insert(key_type const& key)
|
||||||
-> std::enable_if_t<IsKeyCache, ReturnType>
|
-> std::enable_if_t<IsKeyCache, ReturnType>
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
clock_type::time_point const now(m_clock.now());
|
clock_type::time_point const now(m_clock.now());
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
|
||||||
auto [it, inserted] = m_cache.emplace(
|
auto [it, inserted] = m_cache.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::forward_as_tuple(key),
|
std::forward_as_tuple(key),
|
||||||
@@ -652,6 +668,29 @@ TaggedCache<
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Key,
|
||||||
|
class T,
|
||||||
|
bool IsKeyCache,
|
||||||
|
class SharedWeakUnionPointer,
|
||||||
|
class SharedPointerType,
|
||||||
|
class Hash,
|
||||||
|
class KeyEqual,
|
||||||
|
class Mutex>
|
||||||
|
inline auto
|
||||||
|
TaggedCache<
|
||||||
|
Key,
|
||||||
|
T,
|
||||||
|
IsKeyCache,
|
||||||
|
SharedWeakUnionPointer,
|
||||||
|
SharedPointerType,
|
||||||
|
Hash,
|
||||||
|
KeyEqual,
|
||||||
|
Mutex>::peekMutex() -> mutex_type&
|
||||||
|
{
|
||||||
|
return m_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Key,
|
class Key,
|
||||||
class T,
|
class T,
|
||||||
@@ -675,13 +714,10 @@ TaggedCache<
|
|||||||
std::vector<key_type> v;
|
std::vector<key_type> v;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
v.reserve(m_cache.size());
|
v.reserve(m_cache.size());
|
||||||
for (std::size_t i = 0; i < partitionLocks_.size(); ++i)
|
for (auto const& _ : m_cache)
|
||||||
{
|
v.push_back(_.first);
|
||||||
std::lock_guard<Mutex> lock(partitionLocks_[i]);
|
|
||||||
for (auto const& entry : m_cache.map()[i])
|
|
||||||
v.push_back(entry.first);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
@@ -707,12 +743,11 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::rate() const
|
Mutex>::rate() const
|
||||||
{
|
{
|
||||||
auto const hits = m_hits.load(std::memory_order_relaxed);
|
std::lock_guard lock(m_mutex);
|
||||||
auto const misses = m_misses.load(std::memory_order_relaxed);
|
auto const tot = m_hits + m_misses;
|
||||||
auto const tot = hits + misses;
|
|
||||||
if (tot == 0)
|
if (tot == 0)
|
||||||
return 0.0;
|
return 0;
|
||||||
return double(hits) / tot;
|
return double(m_hits) / tot;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@@ -736,16 +771,18 @@ TaggedCache<
|
|||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::fetch(key_type const& digest, Handler const& h)
|
Mutex>::fetch(key_type const& digest, Handler const& h)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(lockPartition(digest));
|
{
|
||||||
|
std::lock_guard l(m_mutex);
|
||||||
if (auto ret = initialFetch(digest))
|
if (auto ret = initialFetch(digest, l))
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
auto sle = h();
|
auto sle = h();
|
||||||
if (!sle)
|
if (!sle)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
m_misses.fetch_add(1, std::memory_order_relaxed);
|
std::lock_guard l(m_mutex);
|
||||||
|
++m_misses;
|
||||||
auto const [it, inserted] =
|
auto const [it, inserted] =
|
||||||
m_cache.emplace(digest, Entry(m_clock.now(), std::move(sle)));
|
m_cache.emplace(digest, Entry(m_clock.now(), std::move(sle)));
|
||||||
if (!inserted)
|
if (!inserted)
|
||||||
@@ -772,10 +809,9 @@ TaggedCache<
|
|||||||
SharedPointerType,
|
SharedPointerType,
|
||||||
Hash,
|
Hash,
|
||||||
KeyEqual,
|
KeyEqual,
|
||||||
Mutex>::initialFetch(key_type const& key)
|
Mutex>::
|
||||||
|
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lock(lockPartition(key));
|
|
||||||
|
|
||||||
auto cit = m_cache.find(key);
|
auto cit = m_cache.find(key);
|
||||||
if (cit == m_cache.end())
|
if (cit == m_cache.end())
|
||||||
return {};
|
return {};
|
||||||
@@ -783,7 +819,7 @@ TaggedCache<
|
|||||||
Entry& entry = cit->second;
|
Entry& entry = cit->second;
|
||||||
if (entry.isCached())
|
if (entry.isCached())
|
||||||
{
|
{
|
||||||
m_hits.fetch_add(1, std::memory_order_relaxed);
|
++m_hits;
|
||||||
entry.touch(m_clock.now());
|
entry.touch(m_clock.now());
|
||||||
return entry.ptr.getStrong();
|
return entry.ptr.getStrong();
|
||||||
}
|
}
|
||||||
@@ -791,13 +827,12 @@ TaggedCache<
|
|||||||
if (entry.isCached())
|
if (entry.isCached())
|
||||||
{
|
{
|
||||||
// independent of cache size, so not counted as a hit
|
// independent of cache size, so not counted as a hit
|
||||||
m_cache_count.fetch_add(1, std::memory_order_relaxed);
|
++m_cache_count;
|
||||||
entry.touch(m_clock.now());
|
entry.touch(m_clock.now());
|
||||||
return entry.ptr.getStrong();
|
return entry.ptr.getStrong();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cache.erase(cit);
|
m_cache.erase(cit);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,11 +861,10 @@ TaggedCache<
|
|||||||
{
|
{
|
||||||
beast::insight::Gauge::value_type hit_rate(0);
|
beast::insight::Gauge::value_type hit_rate(0);
|
||||||
{
|
{
|
||||||
auto const hits = m_hits.load(std::memory_order_relaxed);
|
std::lock_guard lock(m_mutex);
|
||||||
auto const misses = m_misses.load(std::memory_order_relaxed);
|
auto const total(m_hits + m_misses);
|
||||||
auto const total = hits + misses;
|
|
||||||
if (total != 0)
|
if (total != 0)
|
||||||
hit_rate = (hits * 100) / total;
|
hit_rate = (m_hits * 100) / total;
|
||||||
}
|
}
|
||||||
m_stats.hit_rate.set(hit_rate);
|
m_stats.hit_rate.set(hit_rate);
|
||||||
}
|
}
|
||||||
@@ -861,16 +895,12 @@ TaggedCache<
|
|||||||
typename KeyValueCacheType::map_type& partition,
|
typename KeyValueCacheType::map_type& partition,
|
||||||
SweptPointersVector& stuffToSweep,
|
SweptPointersVector& stuffToSweep,
|
||||||
std::atomic<int>& allRemovals,
|
std::atomic<int>& allRemovals,
|
||||||
Mutex& partitionLock)
|
std::lock_guard<std::recursive_mutex> const&)
|
||||||
{
|
{
|
||||||
return std::thread([&, this]() {
|
return std::thread([&, this]() {
|
||||||
beast::setCurrentThreadName("sweep-KVCache");
|
|
||||||
|
|
||||||
int cacheRemovals = 0;
|
int cacheRemovals = 0;
|
||||||
int mapRemovals = 0;
|
int mapRemovals = 0;
|
||||||
|
|
||||||
std::lock_guard<Mutex> lock(partitionLock);
|
|
||||||
|
|
||||||
// Keep references to all the stuff we sweep
|
// Keep references to all the stuff we sweep
|
||||||
// so that we can destroy them outside the lock.
|
// so that we can destroy them outside the lock.
|
||||||
stuffToSweep.reserve(partition.size());
|
stuffToSweep.reserve(partition.size());
|
||||||
@@ -954,16 +984,12 @@ TaggedCache<
|
|||||||
typename KeyOnlyCacheType::map_type& partition,
|
typename KeyOnlyCacheType::map_type& partition,
|
||||||
SweptPointersVector&,
|
SweptPointersVector&,
|
||||||
std::atomic<int>& allRemovals,
|
std::atomic<int>& allRemovals,
|
||||||
Mutex& partitionLock)
|
std::lock_guard<std::recursive_mutex> const&)
|
||||||
{
|
{
|
||||||
return std::thread([&, this]() {
|
return std::thread([&, this]() {
|
||||||
beast::setCurrentThreadName("sweep-KCache");
|
|
||||||
|
|
||||||
int cacheRemovals = 0;
|
int cacheRemovals = 0;
|
||||||
int mapRemovals = 0;
|
int mapRemovals = 0;
|
||||||
|
|
||||||
std::lock_guard<Mutex> lock(partitionLock);
|
|
||||||
|
|
||||||
// Keep references to all the stuff we sweep
|
// Keep references to all the stuff we sweep
|
||||||
// so that we can destroy them outside the lock.
|
// so that we can destroy them outside the lock.
|
||||||
{
|
{
|
||||||
@@ -998,29 +1024,6 @@ TaggedCache<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
|
||||||
class Key,
|
|
||||||
class T,
|
|
||||||
bool IsKeyCache,
|
|
||||||
class SharedWeakUnionPointer,
|
|
||||||
class SharedPointerType,
|
|
||||||
class Hash,
|
|
||||||
class KeyEqual,
|
|
||||||
class Mutex>
|
|
||||||
inline Mutex&
|
|
||||||
TaggedCache<
|
|
||||||
Key,
|
|
||||||
T,
|
|
||||||
IsKeyCache,
|
|
||||||
SharedWeakUnionPointer,
|
|
||||||
SharedPointerType,
|
|
||||||
Hash,
|
|
||||||
KeyEqual,
|
|
||||||
Mutex>::lockPartition(key_type const& key) const
|
|
||||||
{
|
|
||||||
return partitionLocks_[m_cache.partition_index(key)];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -277,12 +277,6 @@ public:
|
|||||||
return map_;
|
return map_;
|
||||||
}
|
}
|
||||||
|
|
||||||
partition_map_type const&
|
|
||||||
map() const
|
|
||||||
{
|
|
||||||
return map_;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator
|
iterator
|
||||||
begin()
|
begin()
|
||||||
{
|
{
|
||||||
@@ -327,12 +321,6 @@ public:
|
|||||||
return cend();
|
return cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
|
||||||
partition_index(key_type const& key) const
|
|
||||||
{
|
|
||||||
return partitioner(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <xrpl/basics/ByteUtilities.h>
|
#include <xrpl/basics/ByteUtilities.h>
|
||||||
#include <xrpl/basics/base_uint.h>
|
#include <xrpl/basics/base_uint.h>
|
||||||
|
#include <xrpl/basics/partitioned_unordered_map.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace BuildInfo {
|
|||||||
// and follow the format described at http://semver.org/
|
// and follow the format described at http://semver.org/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// clang-format off
|
// clang-format off
|
||||||
char const* const versionString = "2.6.0-rc2"
|
char const* const versionString = "2.6.1-rc1"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#if defined(DEBUG) || defined(SANITIZER)
|
#if defined(DEBUG) || defined(SANITIZER)
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ public:
|
|||||||
// Insert an item, retrieve it, and age it so it gets purged.
|
// Insert an item, retrieve it, and age it so it gets purged.
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
BEAST_EXPECT(!c.insert(1, "one"));
|
BEAST_EXPECT(!c.insert(1, "one"));
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert an item, maintain a strong pointer, age it, and
|
// Insert an item, maintain a strong pointer, age it, and
|
||||||
@@ -80,7 +80,7 @@ public:
|
|||||||
{
|
{
|
||||||
BEAST_EXPECT(!c.insert(2, "two"));
|
BEAST_EXPECT(!c.insert(2, "two"));
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = c.fetch(2);
|
auto p = c.fetch(2);
|
||||||
@@ -88,14 +88,14 @@ public:
|
|||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure its gone now that our reference is gone
|
// Make sure its gone now that our reference is gone
|
||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the same key/value pair and make sure we get the same result
|
// Insert the same key/value pair and make sure we get the same result
|
||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put an object in but keep a strong pointer to it, advance the clock a
|
// Put an object in but keep a strong pointer to it, advance the clock a
|
||||||
@@ -121,24 +121,24 @@ public:
|
|||||||
// Put an object in
|
// Put an object in
|
||||||
BEAST_EXPECT(!c.insert(4, "four"));
|
BEAST_EXPECT(!c.insert(4, "four"));
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Keep a strong pointer to it
|
// Keep a strong pointer to it
|
||||||
auto const p1 = c.fetch(4);
|
auto const p1 = c.fetch(4);
|
||||||
BEAST_EXPECT(p1 != nullptr);
|
BEAST_EXPECT(p1 != nullptr);
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
// Advance the clock a lot
|
// Advance the clock a lot
|
||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
// Canonicalize a new object with the same key
|
// Canonicalize a new object with the same key
|
||||||
auto p2 = std::make_shared<std::string>("four");
|
auto p2 = std::make_shared<std::string>("four");
|
||||||
BEAST_EXPECT(c.canonicalize_replace_client(4, p2));
|
BEAST_EXPECT(c.canonicalize_replace_client(4, p2));
|
||||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||||
BEAST_EXPECT(c.size() == 1);
|
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||||
// Make sure we get the original object
|
// Make sure we get the original object
|
||||||
BEAST_EXPECT(p1.get() == p2.get());
|
BEAST_EXPECT(p1.get() == p2.get());
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ public:
|
|||||||
++clock;
|
++clock;
|
||||||
c.sweep();
|
c.sweep();
|
||||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||||
BEAST_EXPECT(c.size() == 0);
|
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -681,7 +681,7 @@ class ServerStatus_test : public beast::unit_test::suite,
|
|||||||
resp["Upgrade"] == "websocket");
|
resp["Upgrade"] == "websocket");
|
||||||
BEAST_EXPECT(
|
BEAST_EXPECT(
|
||||||
resp.find("Connection") != resp.end() &&
|
resp.find("Connection") != resp.end() &&
|
||||||
resp["Connection"] == "Upgrade");
|
resp["Connection"] == "upgrade");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ LedgerHistory::insert(
|
|||||||
ledger->stateMap().getHash().isNonZero(),
|
ledger->stateMap().getHash().isNonZero(),
|
||||||
"ripple::LedgerHistory::insert : nonzero hash");
|
"ripple::LedgerHistory::insert : nonzero hash");
|
||||||
|
|
||||||
|
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||||
|
|
||||||
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)
|
||||||
@@ -74,6 +76,7 @@ LedgerHistory::insert(
|
|||||||
LedgerHash
|
LedgerHash
|
||||||
LedgerHistory::getLedgerHash(LedgerIndex index)
|
LedgerHistory::getLedgerHash(LedgerIndex index)
|
||||||
{
|
{
|
||||||
|
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||||
if (auto it = mLedgersByIndex.find(index); it != mLedgersByIndex.end())
|
if (auto it = mLedgersByIndex.find(index); it != mLedgersByIndex.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
return {};
|
return {};
|
||||||
@@ -83,11 +86,13 @@ std::shared_ptr<Ledger const>
|
|||||||
LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||||
auto it = mLedgersByIndex.find(index);
|
auto it = mLedgersByIndex.find(index);
|
||||||
|
|
||||||
if (it != mLedgersByIndex.end())
|
if (it != mLedgersByIndex.end())
|
||||||
{
|
{
|
||||||
uint256 hash = it->second;
|
uint256 hash = it->second;
|
||||||
|
sl.unlock();
|
||||||
return getLedgerByHash(hash);
|
return getLedgerByHash(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +108,7 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Add this ledger to the local tracking by index
|
// Add this ledger to the local tracking by index
|
||||||
|
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||||
|
|
||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
ret->isImmutable(),
|
ret->isImmutable(),
|
||||||
@@ -452,6 +458,8 @@ LedgerHistory::builtLedger(
|
|||||||
XRPL_ASSERT(
|
XRPL_ASSERT(
|
||||||
!hash.isZero(), "ripple::LedgerHistory::builtLedger : nonzero hash");
|
!hash.isZero(), "ripple::LedgerHistory::builtLedger : nonzero hash");
|
||||||
|
|
||||||
|
std::unique_lock sl(m_consensus_validated.peekMutex());
|
||||||
|
|
||||||
auto entry = std::make_shared<cv_entry>();
|
auto entry = std::make_shared<cv_entry>();
|
||||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||||
|
|
||||||
@@ -492,6 +500,8 @@ LedgerHistory::validatedLedger(
|
|||||||
!hash.isZero(),
|
!hash.isZero(),
|
||||||
"ripple::LedgerHistory::validatedLedger : nonzero hash");
|
"ripple::LedgerHistory::validatedLedger : nonzero hash");
|
||||||
|
|
||||||
|
std::unique_lock sl(m_consensus_validated.peekMutex());
|
||||||
|
|
||||||
auto entry = std::make_shared<cv_entry>();
|
auto entry = std::make_shared<cv_entry>();
|
||||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||||
|
|
||||||
@@ -525,9 +535,10 @@ LedgerHistory::validatedLedger(
|
|||||||
bool
|
bool
|
||||||
LedgerHistory::fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
|
LedgerHistory::fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
|
||||||
{
|
{
|
||||||
auto ledger = m_ledgers_by_hash.fetch(ledgerHash);
|
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||||
auto it = mLedgersByIndex.find(ledgerIndex);
|
auto it = mLedgersByIndex.find(ledgerIndex);
|
||||||
if (ledger && (it != mLedgersByIndex.end()) && (it->second != ledgerHash))
|
|
||||||
|
if ((it != mLedgersByIndex.end()) && (it->second != ledgerHash))
|
||||||
{
|
{
|
||||||
it->second = ledgerHash;
|
it->second = ledgerHash;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ getCountsJson(Application& app, int minObjectCount)
|
|||||||
ret[jss::treenode_cache_size] =
|
ret[jss::treenode_cache_size] =
|
||||||
app.getNodeFamily().getTreeNodeCache()->getCacheSize();
|
app.getNodeFamily().getTreeNodeCache()->getCacheSize();
|
||||||
ret[jss::treenode_track_size] =
|
ret[jss::treenode_track_size] =
|
||||||
static_cast<int>(app.getNodeFamily().getTreeNodeCache()->size());
|
app.getNodeFamily().getTreeNodeCache()->getTrackSize();
|
||||||
|
|
||||||
std::string uptime;
|
std::string uptime;
|
||||||
auto s = UptimeClock::now();
|
auto s = UptimeClock::now();
|
||||||
|
|||||||
Reference in New Issue
Block a user