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,
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
#endif

View File

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

View File

@@ -1450,17 +1450,34 @@ public:
if (ledgerHash)
return *ledgerHash;
// 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
LedgerIndex refIndex = (index + 255) & (~255);
// The hash is not in the reference ledger. Get another ledger which can
// be located easily and should contain the hash.
LedgerIndex refIndex = getCandidateLedger(index);
auto const refHash = hashOfSeq(*referenceLedger, refIndex,
getApp().getSLECache(), m_journal);
assert(refHash);
if (refHash)
{
// We found the hash and sequence of a better reference ledger
auto const ledger =
getApp().getInboundLedgers().acquire (
// Try the hash and sequence of a better reference ledger just found
auto ledger = mLedgerHistory.getLedgerByHash (*refHash);
if (ledger)
{
try
{
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)
{
@@ -1469,6 +1486,7 @@ public:
assert (ledgerHash);
}
}
}
return ledgerHash ? *ledgerHash : zero; // kludge
}

View File

@@ -71,7 +71,7 @@ Json::Value doLedgerRequest (RPC::Context& context)
if (! ledgerHash)
{
// 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,
getApp().getSLECache(), j);
assert(refHash);