mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Compare commits
2 Commits
ximinez/te
...
a1q123456/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47d46ef3ae | ||
|
|
2fd8331d0a |
@@ -37,6 +37,28 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
constexpr bool IsStatelessLambdaV = std::is_empty_v<T> && std::is_constructible_v<T>;
|
||||
|
||||
template<class Lambda, int=(Lambda{}(), 0)>
|
||||
constexpr std::true_type IsConstexpr(Lambda);
|
||||
constexpr std::false_type IsConstexpr(...);
|
||||
|
||||
template <typename T>
|
||||
constexpr bool IsConstexprInvocableV = IsStatelessLambdaV<T> && decltype(IsConstexpr(T{})){};
|
||||
|
||||
template <typename Lambda, bool ConstInvocable = IsConstexprInvocableV<Lambda>>
|
||||
constexpr bool ShouldTakeConstReferenceV = false;
|
||||
|
||||
template <typename Lambda>
|
||||
constexpr bool ShouldTakeConstReferenceV<Lambda, true> = Lambda{}();
|
||||
|
||||
template <typename Lambda>
|
||||
constexpr bool ShouldTakeConstReferenceV<Lambda, false> = true;
|
||||
|
||||
}
|
||||
|
||||
/** Map/cache combination.
|
||||
This class implements a cache and a map. The cache keeps objects alive
|
||||
in the map. The map allows multiple code paths that reference objects
|
||||
@@ -118,6 +140,15 @@ public:
|
||||
del(key_type const& key, bool valid);
|
||||
|
||||
public:
|
||||
|
||||
// We take a const reference if R (the replaceCallback) is a stateless
|
||||
// lambda and can be evaluated at compile time, and it's evaluated to true,
|
||||
// because there's no chance to update the parameter.
|
||||
template <class R>
|
||||
using SharedPointerTypeReference = std::conditional_t<
|
||||
detail::ShouldTakeConstReferenceV<R>,
|
||||
SharedPointerType const&,
|
||||
SharedPointerType&>;
|
||||
/** Replace aliased objects with originals.
|
||||
|
||||
Due to concurrency it is possible for two separate objects with
|
||||
@@ -127,7 +158,7 @@ public:
|
||||
|
||||
@param key The key corresponding to the object
|
||||
@param data A shared pointer to the data corresponding to the object.
|
||||
@param replace Function that decides if cache should be replaced
|
||||
@param replaceCallback Function that decides if cache should be replaced
|
||||
|
||||
@return `true` If the key already existed.
|
||||
*/
|
||||
@@ -135,7 +166,7 @@ public:
|
||||
bool
|
||||
canonicalize(
|
||||
key_type const& key,
|
||||
SharedPointerType& data,
|
||||
SharedPointerTypeReference<R> data,
|
||||
R&& replaceCallback);
|
||||
|
||||
bool
|
||||
|
||||
@@ -415,7 +415,7 @@ TaggedCache<
|
||||
Mutex>::
|
||||
canonicalize(
|
||||
key_type const& key,
|
||||
SharedPointerType& data,
|
||||
SharedPointerTypeReference<R> data,
|
||||
R&& replaceCallback)
|
||||
{
|
||||
// Return canonical value, store if needed, refresh in cache
|
||||
@@ -457,7 +457,7 @@ TaggedCache<
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else
|
||||
else if constexpr (std::assignable_from<decltype(data), decltype(entry.ptr.getStrong())>)
|
||||
{
|
||||
data = entry.ptr.getStrong();
|
||||
}
|
||||
@@ -473,7 +473,7 @@ TaggedCache<
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else
|
||||
else if constexpr (std::assignable_from<decltype(data), decltype(entry.ptr.getStrong())>)
|
||||
{
|
||||
entry.ptr.convertToStrong();
|
||||
data = cachedData;
|
||||
@@ -513,7 +513,7 @@ TaggedCache<
|
||||
SharedPointerType const& data)
|
||||
{
|
||||
return canonicalize(
|
||||
key, const_cast<SharedPointerType&>(data), []() { return true; });
|
||||
key, data, []() { return true; });
|
||||
}
|
||||
|
||||
template <
|
||||
|
||||
@@ -148,6 +148,30 @@ public:
|
||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||
}
|
||||
{
|
||||
BEAST_EXPECT(!c.insert(5, "five"));
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||
|
||||
auto const p1 = c.fetch(5);
|
||||
BEAST_EXPECT(p1 != nullptr);
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||
|
||||
// Advance the clock a lot
|
||||
++clock;
|
||||
c.sweep();
|
||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||
|
||||
auto p2 = std::make_shared<std::string>("five_2");
|
||||
BEAST_EXPECT(c.canonicalize_replace_cache(5, p2));
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.getTrackSize() == 1);
|
||||
// Make sure we get the original object
|
||||
BEAST_EXPECT(p1.get() != p2.get());
|
||||
BEAST_EXPECT(*p2 == "five_2");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user