mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-29 16:12:29 +00:00
adding callback into TaggedCache
This commit is contained in:
@@ -161,6 +161,21 @@ public:
|
||||
fetch(key_type const& digest, Handler const& h);
|
||||
// End CachedSLEs functions.
|
||||
|
||||
/** Fetch or create an entry and execute a callback while holding the lock.
|
||||
|
||||
The entry for the given key is fetched from the cache or created if it
|
||||
doesn't exist. The callback is then invoked with a reference to the
|
||||
entry while the cache mutex is still held, allowing safe modification
|
||||
of the cached object.
|
||||
|
||||
@param key The key to fetch or create
|
||||
@param callback Function to call with the entry under lock.
|
||||
Signature: void(T&)
|
||||
*/
|
||||
template <class Callback>
|
||||
void
|
||||
fetch_and_modify(key_type const& key, Callback&& callback);
|
||||
|
||||
private:
|
||||
SharedPointerType
|
||||
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l);
|
||||
|
||||
@@ -586,6 +586,31 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
|
||||
}
|
||||
// End CachedSLEs functions.
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
bool IsKeyCache,
|
||||
class SharedWeakUnionPointer,
|
||||
class SharedPointerType,
|
||||
class Hash,
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
template <class Callback>
|
||||
inline void
|
||||
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
|
||||
fetch_and_modify(key_type const& key, Callback&& callback)
|
||||
{
|
||||
static_assert(
|
||||
!IsKeyCache, "fetch_and_modify is only supported for value caches, not key-only caches");
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
auto entry = std::make_shared<T>();
|
||||
canonicalize(key, entry, []() { return false; });
|
||||
|
||||
callback(*entry);
|
||||
}
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
|
||||
@@ -412,32 +412,31 @@ LedgerHistory::builtLedger(
|
||||
LedgerHash hash = ledger->header().hash;
|
||||
XRPL_ASSERT(!hash.isZero(), "xrpl::LedgerHistory::builtLedger : nonzero hash");
|
||||
|
||||
auto entry = std::make_shared<cv_entry>();
|
||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||
|
||||
if (entry->validated && !entry->built)
|
||||
{
|
||||
if (entry->validated.value() != hash)
|
||||
m_consensus_validated.fetch_and_modify(index, [&](cv_entry& entry) {
|
||||
if (entry.validated && !entry.built)
|
||||
{
|
||||
JLOG(j_.error()) << "MISMATCH: seq=" << index
|
||||
<< " validated:" << entry->validated.value() << " then:" << hash;
|
||||
handleMismatch(
|
||||
hash,
|
||||
entry->validated.value(),
|
||||
consensusHash,
|
||||
entry->validatedConsensusHash,
|
||||
consensus);
|
||||
if (entry.validated.value() != hash)
|
||||
{
|
||||
JLOG(j_.error()) << "MISMATCH: seq=" << index
|
||||
<< " validated:" << entry.validated.value() << " then:" << hash;
|
||||
handleMismatch(
|
||||
hash,
|
||||
entry.validated.value(),
|
||||
consensusHash,
|
||||
entry.validatedConsensusHash,
|
||||
consensus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We validated a ledger and then built it locally
|
||||
JLOG(j_.debug()) << "MATCH: seq=" << index << " late";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We validated a ledger and then built it locally
|
||||
JLOG(j_.debug()) << "MATCH: seq=" << index << " late";
|
||||
}
|
||||
}
|
||||
|
||||
entry->built.emplace(hash);
|
||||
entry->builtConsensusHash.emplace(consensusHash);
|
||||
entry->consensus.emplace(std::move(consensus));
|
||||
entry.built.emplace(hash);
|
||||
entry.builtConsensusHash.emplace(consensusHash);
|
||||
entry.consensus.emplace(std::move(consensus));
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -449,31 +448,30 @@ LedgerHistory::validatedLedger(
|
||||
LedgerHash hash = ledger->header().hash;
|
||||
XRPL_ASSERT(!hash.isZero(), "xrpl::LedgerHistory::validatedLedger : nonzero hash");
|
||||
|
||||
auto entry = std::make_shared<cv_entry>();
|
||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||
|
||||
if (entry->built && !entry->validated)
|
||||
{
|
||||
if (entry->built.value() != hash)
|
||||
m_consensus_validated.fetch_and_modify(index, [&](cv_entry& entry) {
|
||||
if (entry.built && !entry.validated)
|
||||
{
|
||||
JLOG(j_.error()) << "MISMATCH: seq=" << index << " built:" << entry->built.value()
|
||||
<< " then:" << hash;
|
||||
handleMismatch(
|
||||
entry->built.value(),
|
||||
hash,
|
||||
entry->builtConsensusHash,
|
||||
consensusHash,
|
||||
entry->consensus.value());
|
||||
if (entry.built.value() != hash)
|
||||
{
|
||||
JLOG(j_.error()) << "MISMATCH: seq=" << index << " built:" << entry.built.value()
|
||||
<< " then:" << hash;
|
||||
handleMismatch(
|
||||
entry.built.value(),
|
||||
hash,
|
||||
entry.builtConsensusHash,
|
||||
consensusHash,
|
||||
entry.consensus.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// We built a ledger locally and then validated it
|
||||
JLOG(j_.debug()) << "MATCH: seq=" << index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We built a ledger locally and then validated it
|
||||
JLOG(j_.debug()) << "MATCH: seq=" << index;
|
||||
}
|
||||
}
|
||||
|
||||
entry->validated.emplace(hash);
|
||||
entry->validatedConsensusHash = consensusHash;
|
||||
entry.validated.emplace(hash);
|
||||
entry.validatedConsensusHash = consensusHash;
|
||||
});
|
||||
}
|
||||
|
||||
/** Ensure m_ledgers_by_hash doesn't have the wrong hash for a particular index
|
||||
|
||||
Reference in New Issue
Block a user