Rename canonicalize into two functions:

* canonicalize_replace_cache
* canonicalize_replace_client

Now it is clear at the call site that if there are
duplicate copies of the data between the cache and
the caller, which copy gets replaced.

Additionally data parameter is now const-correct.
If it is not going to be replaced (canonicalize_replace_cache),
then the shared_ptr to the client data is const.
This commit is contained in:
Howard Hinnant
2020-03-05 15:53:12 -05:00
committed by manojsdoshi
parent e257a226f3
commit f22fcb3b2a
12 changed files with 42 additions and 24 deletions

View File

@@ -835,7 +835,7 @@ static bool saveValidatedLedger (
if (! aLedger) if (! aLedger)
{ {
aLedger = std::make_shared<AcceptedLedger>(ledger, app.accountIDCache(), app.logs()); aLedger = std::make_shared<AcceptedLedger>(ledger, app.accountIDCache(), app.logs());
app.getAcceptedLedgerCache().canonicalize(ledger->info().hash, aLedger); app.getAcceptedLedgerCache().canonicalize_replace_client(ledger->info().hash, aLedger);
} }
} }
catch (std::exception const&) catch (std::exception const&)

View File

@@ -62,8 +62,8 @@ LedgerHistory::insert(
std::unique_lock sl (m_ledgers_by_hash.peekMutex ()); std::unique_lock sl (m_ledgers_by_hash.peekMutex ());
const bool alreadyHad = m_ledgers_by_hash.canonicalize ( const bool alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(
ledger->info().hash, ledger, true); ledger->info().hash, ledger);
if (validated) if (validated)
mLedgersByIndex[ledger->info().seq] = ledger->info().hash; mLedgersByIndex[ledger->info().seq] = ledger->info().hash;
@@ -108,7 +108,7 @@ LedgerHistory::getLedgerBySeq (LedgerIndex index)
std::unique_lock sl (m_ledgers_by_hash.peekMutex ()); std::unique_lock sl (m_ledgers_by_hash.peekMutex ());
assert (ret->isImmutable ()); assert (ret->isImmutable ());
m_ledgers_by_hash.canonicalize (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;
return (ret->info().seq == index) ? ret : nullptr; return (ret->info().seq == index) ? ret : nullptr;
} }
@@ -133,7 +133,7 @@ LedgerHistory::getLedgerByHash (LedgerHash const& hash)
assert (ret->isImmutable ()); assert (ret->isImmutable ());
assert (ret->info().hash == hash); assert (ret->info().hash == hash);
m_ledgers_by_hash.canonicalize (ret->info().hash, ret); m_ledgers_by_hash.canonicalize_replace_client(ret->info().hash, ret);
assert (ret->info().hash == hash); assert (ret->info().hash == hash);
return ret; return ret;
@@ -432,7 +432,7 @@ void LedgerHistory::builtLedger (
m_consensus_validated.peekMutex()); m_consensus_validated.peekMutex());
auto entry = std::make_shared<cv_entry>(); auto entry = std::make_shared<cv_entry>();
m_consensus_validated.canonicalize(index, entry, false); m_consensus_validated.canonicalize_replace_client(index, entry);
if (entry->validated && ! entry->built) if (entry->validated && ! entry->built)
{ {
@@ -472,7 +472,7 @@ void LedgerHistory::validatedLedger (
m_consensus_validated.peekMutex()); m_consensus_validated.peekMutex());
auto entry = std::make_shared<cv_entry>(); auto entry = std::make_shared<cv_entry>();
m_consensus_validated.canonicalize(index, entry, false); m_consensus_validated.canonicalize_replace_client(index, entry);
if (entry->built && ! entry->validated) if (entry->built && ! entry->validated)
{ {

View File

@@ -1976,7 +1976,7 @@ LedgerMaster::addFetchPack (
uint256 const& hash, uint256 const& hash,
std::shared_ptr< Blob >& data) std::shared_ptr< Blob >& data)
{ {
fetch_packs_.canonicalize (hash, data); fetch_packs_.canonicalize_replace_client(hash, data);
} }
boost::optional<Blob> boost::optional<Blob>

View File

@@ -62,7 +62,7 @@ TransactionMaster::fetch (uint256 const& txnID, error_code_i& ec)
if (!txn) if (!txn)
return txn; return txn;
mCache.canonicalize (txnID, txn); mCache.canonicalize_replace_client(txnID, txn);
return txn; return txn;
} }
@@ -82,7 +82,7 @@ TransactionMaster::fetch (uint256 const& txnID, ClosedInterval<uint32_t> const&
txnID, mApp, range, ec); txnID, mApp, range, ec);
if (v.which () == 0 && boost::get<pointer> (v)) if (v.which () == 0 && boost::get<pointer> (v))
mCache.canonicalize (txnID, boost::get<pointer> (v)); mCache.canonicalize_replace_client(txnID, boost::get<pointer> (v));
return v; return v;
} }
@@ -127,7 +127,7 @@ TransactionMaster::canonicalize(std::shared_ptr<Transaction>* pTransaction)
{ {
auto txn = *pTransaction; auto txn = *pTransaction;
// VFALCO NOTE canonicalize can change the value of txn! // VFALCO NOTE canonicalize can change the value of txn!
mCache.canonicalize(tid, txn); mCache.canonicalize_replace_client(tid, txn);
*pTransaction = txn; *pTransaction = txn;
} }
} }

View File

@@ -2665,7 +2665,7 @@ void NetworkOPsImp::pubLedger (
{ {
alpAccepted = std::make_shared<AcceptedLedger> ( alpAccepted = std::make_shared<AcceptedLedger> (
lpAccepted, app_.accountIDCache(), app_.logs()); lpAccepted, app_.accountIDCache(), app_.logs());
app_.getAcceptedLedgerCache().canonicalize ( app_.getAcceptedLedgerCache().canonicalize_replace_client(
lpAccepted->info().hash, alpAccepted); lpAccepted->info().hash, alpAccepted);
} }

View File

@@ -288,7 +288,14 @@ public:
@return `true` If the key already existed. @return `true` If the key already existed.
*/ */
bool canonicalize (const key_type& key, std::shared_ptr<T>& data, bool replace = false) private:
template <bool replace>
bool
canonicalize(
const key_type& key,
std::conditional_t<replace, std::shared_ptr<T> const, std::shared_ptr<T>>& data
)
{ {
// 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
@@ -310,7 +317,7 @@ public:
if (entry.isCached ()) if (entry.isCached ())
{ {
if (replace) if constexpr (replace)
{ {
entry.ptr = data; entry.ptr = data;
entry.weak_ptr = data; entry.weak_ptr = data;
@@ -327,7 +334,7 @@ public:
if (cachedData) if (cachedData)
{ {
if (replace) if constexpr (replace)
{ {
entry.ptr = data; entry.ptr = data;
entry.weak_ptr = data; entry.weak_ptr = data;
@@ -349,6 +356,17 @@ public:
return false; return false;
} }
public:
bool canonicalize_replace_cache(const key_type& key, std::shared_ptr<T> const& data)
{
return canonicalize<true>(key, data);
}
bool canonicalize_replace_client(const key_type& key, std::shared_ptr<T>& data)
{
return canonicalize<false>(key, data);
}
std::shared_ptr<T> fetch (const key_type& key) std::shared_ptr<T> fetch (const key_type& key)
{ {
// fetch us a shared pointer to the stored data object // fetch us a shared pointer to the stored data object
@@ -393,7 +411,7 @@ public:
{ {
mapped_ptr p (std::make_shared <T> ( mapped_ptr p (std::make_shared <T> (
std::cref (value))); std::cref (value)));
return canonicalize (key, p); return canonicalize_replace_client(key, p);
} }
// VFALCO NOTE It looks like this returns a copy of the data in // VFALCO NOTE It looks like this returns a copy of the data in

View File

@@ -216,7 +216,7 @@ Database::doFetch(uint256 const& hash, std::uint32_t seq,
else else
{ {
// Ensure all threads get the same object // Ensure all threads get the same object
pCache.canonicalize(hash, nObj); pCache.canonicalize_replace_client(hash, nObj);
// Since this was a 'hard' fetch, we will log it. // Since this was a 'hard' fetch, we will log it.
JLOG(j_.trace()) << JLOG(j_.trace()) <<
@@ -265,7 +265,7 @@ Database::storeLedger(
{ {
for (auto& nObj : batch) for (auto& nObj : batch)
{ {
dstPCache->canonicalize(nObj->getHash(), nObj, true); dstPCache->canonicalize_replace_cache(nObj->getHash(), nObj);
dstNCache->erase(nObj->getHash()); dstNCache->erase(nObj->getHash());
storeStats(nObj->getData().size()); storeStats(nObj->getData().size());
} }

View File

@@ -29,7 +29,7 @@ DatabaseNodeImp::store(NodeObjectType type, Blob&& data,
uint256 const& hash, std::uint32_t seq) uint256 const& hash, std::uint32_t seq)
{ {
auto nObj = NodeObject::createObject(type, std::move(data), hash); auto nObj = NodeObject::createObject(type, std::move(data), hash);
pCache_->canonicalize(hash, nObj, true); pCache_->canonicalize_replace_cache(hash, nObj);
backend_->store(nObj); backend_->store(nObj);
nCache_->erase(hash); nCache_->erase(hash);
storeStats(nObj->getData().size()); storeStats(nObj->getData().size());

View File

@@ -64,7 +64,7 @@ DatabaseRotatingImp::store(NodeObjectType type, Blob&& data,
uint256 const& hash, std::uint32_t seq) uint256 const& hash, std::uint32_t seq)
{ {
auto nObj = NodeObject::createObject(type, std::move(data), hash); auto nObj = NodeObject::createObject(type, std::move(data), hash);
pCache_->canonicalize(hash, nObj, true); pCache_->canonicalize_replace_cache(hash, nObj);
getWritableBackend()->store(nObj); getWritableBackend()->store(nObj);
nCache_->erase(hash); nCache_->erase(hash);
storeStats(nObj->getData().size()); storeStats(nObj->getData().size());

View File

@@ -892,7 +892,7 @@ DatabaseShardImp::store(
auto [backend, pCache, nCache] = shard->getBackendAll(); auto [backend, pCache, nCache] = shard->getBackendAll();
auto nObj {NodeObject::createObject(type, std::move(data), hash)}; auto nObj {NodeObject::createObject(type, std::move(data), hash)};
pCache->canonicalize(hash, nObj, true); pCache->canonicalize_replace_cache(hash, nObj);
backend->store(nObj); backend->store(nObj);
nCache->erase(hash); nCache->erase(hash);

View File

@@ -1072,7 +1072,7 @@ SHAMap::canonicalize(SHAMapHash const& hash, std::shared_ptr<SHAMapAbstractNode>
assert (node->getSeq() == 0); assert (node->getSeq() == 0);
assert (node->getNodeHash() == hash); assert (node->getNodeHash() == hash);
f_.treecache().canonicalize (hash.as_uint256(), node); f_.treecache().canonicalize_replace_client(hash.as_uint256(), node);
} }
void void

View File

@@ -103,7 +103,7 @@ public:
{ {
Cache::mapped_ptr const p1 (c.fetch (3)); Cache::mapped_ptr const p1 (c.fetch (3));
Cache::mapped_ptr p2 (std::make_shared <Value> ("three")); Cache::mapped_ptr p2 (std::make_shared <Value> ("three"));
c.canonicalize (3, p2); c.canonicalize_replace_client(3, p2);
BEAST_EXPECT(p1.get() == p2.get()); BEAST_EXPECT(p1.get() == p2.get());
} }
++clock; ++clock;
@@ -134,7 +134,7 @@ public:
BEAST_EXPECT(c.getTrackSize() == 1); BEAST_EXPECT(c.getTrackSize() == 1);
// Canonicalize a new object with the same key // Canonicalize a new object with the same key
Cache::mapped_ptr p2 (std::make_shared <std::string> ("four")); Cache::mapped_ptr p2 (std::make_shared <std::string> ("four"));
BEAST_EXPECT(c.canonicalize (4, p2, false)); BEAST_EXPECT(c.canonicalize_replace_client(4, p2));
BEAST_EXPECT(c.getCacheSize() == 1); BEAST_EXPECT(c.getCacheSize() == 1);
BEAST_EXPECT(c.getTrackSize() == 1); BEAST_EXPECT(c.getTrackSize() == 1);
// Make sure we get the original object // Make sure we get the original object