Acquire logic fixes:

In InboundLedgers::acquire, properly return a ledger if we are
able to create one immediately.

In LedgerMaster::walkHashBySeq, don't walk the whole ledger if
we already know we have it.
This commit is contained in:
Nik Bougalis
2015-06-09 01:40:24 -07:00
parent 2904add428
commit e980e69eca
5 changed files with 66 additions and 30 deletions

View File

@@ -545,6 +545,25 @@ boost::optional<uint256>
hashOfSeq (Ledger& ledger, LedgerIndex seq, hashOfSeq (Ledger& ledger, LedgerIndex seq,
SLECache& cache, beast::Journal journal); SLECache& cache, beast::Journal journal);
/** Find a ledger index from which we could easily get the requested ledger
The index that we return should meet two requirements:
1) It must be the index of a ledger that has the hash of the ledger
we are looking for. This means that its sequence must be equal to
greater than the sequence that we want but not more than 256 greater
since each ledger contains the hashes of the 256 previous ledgers.
2) Its hash must be easy for us to find. This means it must be 0 mod 256
because every such ledger is permanently enshrined in a LedgerHashes
page which we can easily retrieve via the skip list.
*/
inline
LedgerIndex
getCandidateLedger (LedgerIndex requested)
{
return (requested + 255) & (~255);
}
} // ripple } // ripple
#endif #endif

View File

@@ -57,8 +57,7 @@ public:
Ledger::pointer acquire (uint256 const& hash, std::uint32_t seq, InboundLedger::fcReason reason) Ledger::pointer acquire (uint256 const& hash, std::uint32_t seq, InboundLedger::fcReason reason)
{ {
assert (hash.isNonZero ()); assert (hash.isNonZero ());
Ledger::pointer ret; InboundLedger::pointer inbound;
{ {
ScopedLockType sl (mLock); ScopedLockType sl (mLock);
@@ -67,26 +66,26 @@ public:
auto it = mLedgers.find (hash); auto it = mLedgers.find (hash);
if (it != mLedgers.end ()) if (it != mLedgers.end ())
{ {
// Don't touch failed acquires so they can expire inbound = it->second;
if (! it->second->isFailed ())
{
it->second->update (seq);
if (it->second->isComplete ())
ret = it->second->getLedger ();
}
// If the acquisition failed, don't mark the item as
// recently accessed so that it can expire.
if (! inbound->isFailed ())
inbound->update (seq);
} }
else else
{ {
auto il = std::make_shared <InboundLedger> (hash, seq, reason, std::ref (m_clock)); inbound = std::make_shared <InboundLedger> (
mLedgers.insert (std::make_pair (hash, il)); hash, seq, reason, std::ref (m_clock));
il->init (sl); mLedgers.emplace (hash, inbound);
inbound->init (sl);
++mCounter; ++mCounter;
} }
} }
} }
if (inbound && inbound->isComplete ())
return ret; return inbound->getLedger();
return {};
} }
InboundLedger::pointer find (uint256 const& hash) InboundLedger::pointer find (uint256 const& hash)

View File

@@ -352,7 +352,7 @@ public:
{ {
// No, Try to get another ledger that might have the hash we need // No, Try to get another ledger that might have the hash we need
// Compute the index and hash of a ledger that will have the hash we need // Compute the index and hash of a ledger that will have the hash we need
LedgerIndex refIndex = (ledgerIndex + 255) & (~255); LedgerIndex refIndex = getCandidateLedger (ledgerIndex);
LedgerHash refHash = getLedgerHash (referenceLedger, refIndex); LedgerHash refHash = getLedgerHash (referenceLedger, refIndex);
bool const nonzero (refHash.isNonZero ()); bool const nonzero (refHash.isNonZero ());

View File

@@ -1450,23 +1450,41 @@ public:
if (ledgerHash) if (ledgerHash)
return *ledgerHash; return *ledgerHash;
// No, Try to get another ledger that might have the hash we need // The hash is not in the reference ledger. Get another ledger which can
// Compute the index and hash of a ledger that will have the hash we need // be located easily and should contain the hash.
LedgerIndex refIndex = (index + 255) & (~255); LedgerIndex refIndex = getCandidateLedger(index);
auto const refHash = hashOfSeq(*referenceLedger, refIndex, auto const refHash = hashOfSeq(*referenceLedger, refIndex,
getApp().getSLECache(), m_journal); getApp().getSLECache(), m_journal);
assert(refHash); assert(refHash);
if (refHash) if (refHash)
{ {
// We found the hash and sequence of a better reference ledger // Try the hash and sequence of a better reference ledger just found
auto const ledger = auto ledger = mLedgerHistory.getLedgerByHash (*refHash);
getApp().getInboundLedgers().acquire (
*refHash, refIndex, InboundLedger::fcGENERIC);
if (ledger) if (ledger)
{ {
ledgerHash = hashOfSeq(*ledger, index, try
getApp().getSLECache(), m_journal); {
assert (ledgerHash); ledgerHash = hashOfSeq(*ledger, index,
getApp().getSLECache(), m_journal);
}
catch(SHAMapMissingNode&)
{
ledger.reset();
}
}
// Try to acquire the complete ledger
if (!ledger)
{
auto const ledger = getApp().getInboundLedgers().acquire (
*refHash, refIndex, InboundLedger::fcGENERIC);
if (ledger)
{
ledgerHash = hashOfSeq(*ledger, index,
getApp().getSLECache(), m_journal);
assert (ledgerHash);
}
} }
} }
return ledgerHash ? *ledgerHash : zero; // kludge return ledgerHash ? *ledgerHash : zero; // kludge

View File

@@ -71,7 +71,7 @@ Json::Value doLedgerRequest (RPC::Context& context)
if (! ledgerHash) if (! ledgerHash)
{ {
// Find a ledger more likely to have the hash of the desired ledger // Find a ledger more likely to have the hash of the desired ledger
auto refIndex = (ledgerIndex + 255) & (~255); auto const refIndex = getCandidateLedger(ledgerIndex);
auto refHash = hashOfSeq(*ledger, refIndex, auto refHash = hashOfSeq(*ledger, refIndex,
getApp().getSLECache(), j); getApp().getSLECache(), j);
assert(refHash); assert(refHash);