mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-02 03:52:13 +00:00
Compare commits
12 Commits
ximinez/pa
...
ximinez/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d2bc88a2e | ||
|
|
9c03931190 | ||
|
|
4f0738fff3 | ||
|
|
1a3d460046 | ||
|
|
c2e54d12e9 | ||
|
|
0ded97ba5b | ||
|
|
0e8714af73 | ||
|
|
d62ad9a8e7 | ||
|
|
d7e7baa675 | ||
|
|
054284701e | ||
|
|
eb4681da51 | ||
|
|
9b3dd7002d |
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.ipp>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/basics/scope.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -595,8 +598,39 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
std::vector<key_type> v;
|
||||
|
||||
{
|
||||
std::scoped_lock const lock(mutex_);
|
||||
v.reserve(cache_.size());
|
||||
// Keep track of how many iterations are needed. Exit the loop if the number of retries gets
|
||||
// absurd. (Note that if this somehow ever happens, one more allocation will be done under
|
||||
// lock, which is undesirable, but really should be almost impossible.)
|
||||
std::size_t allocationIterations = 0;
|
||||
std::unique_lock lock(mutex_);
|
||||
for (auto size = cache_.size(); v.capacity() < size && allocationIterations < 20;
|
||||
size = cache_.size())
|
||||
{
|
||||
ScopeUnlock const unlock(lock);
|
||||
// Allocate the current size plus a little extra, in case the cache grows while
|
||||
// allocating. Each time another allocation is needed, the extra also gets bigger until
|
||||
// it ultimately doubles the size + 1.
|
||||
size += (size >> (4 - std::min(allocationIterations, std::size_t{4}))) + 1;
|
||||
v.reserve(size);
|
||||
++allocationIterations;
|
||||
}
|
||||
// In a normal operating environment, because of the padding added to size before
|
||||
// allocating, even 2 iterations is going to be very rare. If 3 or more are ever needed,
|
||||
// that's unusual enough that I want to know about it. Don't ask me to change it without
|
||||
// empirical data. - Ed H.
|
||||
XRPL_ASSERT(
|
||||
allocationIterations < 3,
|
||||
"xrpl::TaggedCache::getKeys(): limited allocation iterations");
|
||||
if (v.capacity() < cache_.size())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::TaggedCache::getKeys(): failed to allocate sufficient capacity");
|
||||
v.reserve(cache_.size());
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
XRPL_ASSERT(lock.owns_lock(), "xrpl::TaggedCache::getKeys(): owns lock");
|
||||
XRPL_ASSERT(
|
||||
v.capacity() >= cache_.size(), "xrpl::TaggedCache::getKeys(): sufficient capacity");
|
||||
for (auto const& _ : cache_)
|
||||
v.push_back(_.first);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user