Replace uses of dirDelete with ApplyView::dirRemove

This commit is contained in:
Joe Loser
2018-05-21 22:39:24 -04:00
committed by Nik Bougalis
parent b0a1aef43d
commit 243e181c08
9 changed files with 107 additions and 301 deletions

View File

@@ -911,201 +911,6 @@ dirAdd (ApplyView& view,
return uNodeDir;
}
// Ledger must be in a state for this to work.
TER
dirDelete (ApplyView& view,
const bool bKeepRoot, // --> True, if we never completely clean up, after we overflow the root node.
std::uint64_t uNodeDir, // --> Node containing entry.
Keylet const& root, // --> The index of the base of the directory. Nodes are based off of this.
uint256 const& uLedgerIndex, // --> Value to remove from directory.
const bool bStable, // --> True, not to change relative order of entries.
const bool bSoft, // --> True, uNodeDir is not hard and fast (pass uNodeDir=0).
beast::Journal j)
{
if (view.rules().enabled(featureSortedDirectories))
{
if (view.dirRemove(root, uNodeDir, uLedgerIndex, bKeepRoot))
return tesSUCCESS;
return tefBAD_LEDGER;
}
std::uint64_t uNodeCur = uNodeDir;
SLE::pointer sleNode =
view.peek(keylet::page(root, uNodeCur));
if (!sleNode)
{
JLOG (j.warn()) << "dirDelete: no such node:" <<
" root=" << to_string (root.key) <<
" uNodeDir=" << strHex (uNodeDir) <<
" uLedgerIndex=" << to_string (uLedgerIndex);
if (!bSoft)
{
assert (false);
return tefBAD_LEDGER;
}
else if (uNodeDir < 20)
{
// Go the extra mile. Even if node doesn't exist, try the next node.
return dirDelete (view, bKeepRoot,
uNodeDir + 1, root, uLedgerIndex, bStable, true, j);
}
else
{
return tefBAD_LEDGER;
}
}
STVector256 svIndexes = sleNode->getFieldV256 (sfIndexes);
auto it = std::find (svIndexes.begin (), svIndexes.end (), uLedgerIndex);
if (svIndexes.end () == it)
{
if (!bSoft)
{
assert (false);
JLOG (j.warn()) << "dirDelete: no such entry";
return tefBAD_LEDGER;
}
if (uNodeDir < 20)
{
// Go the extra mile. Even if entry not in node, try the next node.
return dirDelete (view, bKeepRoot, uNodeDir + 1,
root, uLedgerIndex, bStable, true, j);
}
return tefBAD_LEDGER;
}
// Remove the element.
if (svIndexes.size () > 1)
{
if (bStable)
{
svIndexes.erase (it);
}
else
{
*it = svIndexes[svIndexes.size () - 1];
svIndexes.resize (svIndexes.size () - 1);
}
}
else
{
svIndexes.clear ();
}
sleNode->setFieldV256 (sfIndexes, svIndexes);
view.update(sleNode);
if (svIndexes.empty ())
{
// May be able to delete nodes.
std::uint64_t uNodePrevious = sleNode->getFieldU64 (sfIndexPrevious);
std::uint64_t uNodeNext = sleNode->getFieldU64 (sfIndexNext);
if (!uNodeCur)
{
// Just emptied root node.
if (!uNodePrevious)
{
// Never overflowed the root node. Delete it.
view.erase(sleNode);
}
// Root overflowed.
else if (bKeepRoot)
{
// If root overflowed and not allowed to delete overflowed root node.
}
else if (uNodePrevious != uNodeNext)
{
// Have more than 2 nodes. Can't delete root node.
}
else
{
// Have only a root node and a last node.
auto sleLast = view.peek(keylet::page(root, uNodeNext));
assert (sleLast);
if (sleLast->getFieldV256 (sfIndexes).empty ())
{
// Both nodes are empty.
view.erase (sleNode); // Delete root.
view.erase (sleLast); // Delete last.
}
else
{
// Have an entry, can't delete root node.
}
}
}
// Just emptied a non-root node.
else if (uNodeNext)
{
// Not root and not last node. Can delete node.
auto slePrevious = view.peek(keylet::page(root, uNodePrevious));
auto sleNext = view.peek(keylet::page(root, uNodeNext));
assert (slePrevious);
if (!slePrevious)
{
JLOG (j.warn()) << "dirDelete: previous node is missing";
return tefBAD_LEDGER;
}
assert (sleNext);
if (!sleNext)
{
JLOG (j.warn()) << "dirDelete: next node is missing";
return tefBAD_LEDGER;
}
// Fix previous to point to its new next.
slePrevious->setFieldU64 (sfIndexNext, uNodeNext);
view.update (slePrevious);
// Fix next to point to its new previous.
sleNext->setFieldU64 (sfIndexPrevious, uNodePrevious);
view.update (sleNext);
view.erase(sleNode);
}
// Last node.
else if (bKeepRoot || uNodePrevious)
{
// Not allowed to delete last node as root was overflowed.
// Or, have pervious entries preventing complete delete.
}
else
{
// Last and only node besides the root.
auto sleRoot = view.peek(root);
assert (sleRoot);
if (sleRoot->getFieldV256 (sfIndexes).empty ())
{
// Both nodes are empty.
view.erase(sleRoot); // Delete root.
view.erase(sleNode); // Delete last.
}
else
{
// Root has an entry, can't delete.
}
}
}
return tesSUCCESS;
}
TER
trustCreate (ApplyView& view,
const bool bSrcHigh,
@@ -1216,41 +1021,37 @@ trustDelete (ApplyView& view,
beast::Journal j)
{
// Detect legacy dirs.
bool bLowNode = sleRippleState->isFieldPresent (sfLowNode);
bool bHighNode = sleRippleState->isFieldPresent (sfHighNode);
std::uint64_t uLowNode = sleRippleState->getFieldU64 (sfLowNode);
std::uint64_t uHighNode = sleRippleState->getFieldU64 (sfHighNode);
TER terResult;
JLOG (j.trace())
<< "trustDelete: Deleting ripple line: low";
terResult = dirDelete(view,
false,
uLowNode,
keylet::ownerDir (uLowAccountID),
sleRippleState->key(),
false,
!bLowNode,
j);
if (tesSUCCESS == terResult)
{
JLOG (j.trace())
<< "trustDelete: Deleting ripple line: high";
terResult = dirDelete (view,
false,
uHighNode,
keylet::ownerDir (uHighAccountID),
if (! view.dirRemove(
keylet::ownerDir(uLowAccountID),
uLowNode,
sleRippleState->key(),
false,
!bHighNode,
j);
false))
{
return tefBAD_LEDGER;
}
JLOG (j.trace())
<< "trustDelete: Deleting ripple line: high";
if (! view.dirRemove(
keylet::ownerDir(uHighAccountID),
uHighNode,
sleRippleState->key(),
false))
{
return tefBAD_LEDGER;
}
JLOG (j.trace()) << "trustDelete: Deleting ripple line: state";
view.erase(sleRippleState);
return terResult;
return tesSUCCESS;
}
TER
@@ -1264,22 +1065,32 @@ offerDelete (ApplyView& view,
auto owner = sle->getAccountID (sfAccount);
// Detect legacy directories.
bool bOwnerNode = sle->isFieldPresent (sfOwnerNode);
uint256 uDirectory = sle->getFieldH256 (sfBookDirectory);
TER terResult = dirDelete (view, false, sle->getFieldU64 (sfOwnerNode),
keylet::ownerDir (owner), offerIndex, false, !bOwnerNode, j);
TER terResult2 = dirDelete (view, false, sle->getFieldU64 (sfBookNode),
keylet::page (uDirectory), offerIndex, true, false, j);
if (! view.dirRemove(
keylet::ownerDir(owner),
sle->getFieldU64(sfOwnerNode),
offerIndex,
false))
{
return tefBAD_LEDGER;
}
if (tesSUCCESS == terResult)
adjustOwnerCount(view, view.peek(
keylet::account(owner)), -1, j);
if (! view.dirRemove(
keylet::page(uDirectory),
sle->getFieldU64(sfBookNode),
offerIndex,
false))
{
return tefBAD_LEDGER;
}
adjustOwnerCount(view, view.peek(
keylet::account(owner)), -1, j);
view.erase(sle);
return (terResult == tesSUCCESS) ?
terResult2 : terResult;
return tesSUCCESS;
}
// Direct send w/o fees: