mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Reformatting using AStyle
This commit is contained in:
@@ -8,214 +8,244 @@
|
||||
|
||||
class SHAMapDeltaNode
|
||||
{
|
||||
public:
|
||||
SHAMapNode mNodeID;
|
||||
uint256 mOurHash, mOtherHash;
|
||||
|
||||
SHAMapDeltaNode(const SHAMapNode& id, uint256 const& ourHash, uint256 const& otherHash) :
|
||||
mNodeID(id), mOurHash(ourHash), mOtherHash(otherHash) { ; }
|
||||
public:
|
||||
SHAMapNode mNodeID;
|
||||
uint256 mOurHash, mOtherHash;
|
||||
|
||||
SHAMapDeltaNode (const SHAMapNode& id, uint256 const& ourHash, uint256 const& otherHash) :
|
||||
mNodeID (id), mOurHash (ourHash), mOtherHash (otherHash)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
bool SHAMap::walkBranch(SHAMapTreeNode* node, SHAMapItem::ref otherMapItem, bool isFirstMap,
|
||||
Delta& differences, int& maxCount)
|
||||
bool SHAMap::walkBranch (SHAMapTreeNode* node, SHAMapItem::ref otherMapItem, bool isFirstMap,
|
||||
Delta& differences, int& maxCount)
|
||||
{
|
||||
// Walk a branch of a SHAMap that's matched by an empty branch or single item in the other map
|
||||
std::stack<SHAMapTreeNode*> nodeStack;
|
||||
nodeStack.push(node);
|
||||
// Walk a branch of a SHAMap that's matched by an empty branch or single item in the other map
|
||||
std::stack<SHAMapTreeNode*> nodeStack;
|
||||
nodeStack.push (node);
|
||||
|
||||
bool emptyBranch = !otherMapItem;
|
||||
bool emptyBranch = !otherMapItem;
|
||||
|
||||
while (!nodeStack.empty())
|
||||
{
|
||||
SHAMapTreeNode* node = nodeStack.top();
|
||||
nodeStack.pop();
|
||||
if (node->isInner())
|
||||
{ // This is an inner node, add all non-empty branches
|
||||
for(int i = 0; i < 16; ++i)
|
||||
if (!node->isEmptyBranch(i))
|
||||
nodeStack.push(getNodePointer(node->getChildNodeID(i), node->getChildHash(i)));
|
||||
}
|
||||
else
|
||||
{ // This is a leaf node, process its item
|
||||
SHAMapItem::pointer item = node->getItem();
|
||||
while (!nodeStack.empty ())
|
||||
{
|
||||
SHAMapTreeNode* node = nodeStack.top ();
|
||||
nodeStack.pop ();
|
||||
|
||||
if (!emptyBranch && (otherMapItem->getTag() < item->getTag()))
|
||||
{ // this item comes after the item from the other map, so add the other item
|
||||
if (isFirstMap) // this is first map, so other item is from second
|
||||
differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(SHAMapItem::pointer(), otherMapItem)));
|
||||
else
|
||||
differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(otherMapItem, SHAMapItem::pointer())));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
emptyBranch = true;
|
||||
}
|
||||
if (node->isInner ())
|
||||
{
|
||||
// This is an inner node, add all non-empty branches
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if (!node->isEmptyBranch (i))
|
||||
nodeStack.push (getNodePointer (node->getChildNodeID (i), node->getChildHash (i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a leaf node, process its item
|
||||
SHAMapItem::pointer item = node->getItem ();
|
||||
|
||||
if (emptyBranch || (item->getTag() != otherMapItem->getTag()))
|
||||
{ // unmatched
|
||||
if (isFirstMap)
|
||||
differences.insert(std::make_pair(item->getTag(), std::make_pair(item, SHAMapItem::pointer())));
|
||||
else
|
||||
differences.insert(std::make_pair(item->getTag(), std::make_pair(SHAMapItem::pointer(), item)));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->peekData() != otherMapItem->peekData())
|
||||
{ // non-matching items
|
||||
if (isFirstMap) differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(item, otherMapItem)));
|
||||
else differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(otherMapItem, item)));
|
||||
if(--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
emptyBranch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!emptyBranch)
|
||||
{ // otherMapItem was unmatched, must add
|
||||
if (isFirstMap) // this is first map, so other item is from second
|
||||
differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(SHAMapItem::pointer(), otherMapItem)));
|
||||
else
|
||||
differences.insert(std::make_pair(otherMapItem->getTag(),
|
||||
std::make_pair(otherMapItem, SHAMapItem::pointer())));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!emptyBranch && (otherMapItem->getTag () < item->getTag ()))
|
||||
{
|
||||
// this item comes after the item from the other map, so add the other item
|
||||
if (isFirstMap) // this is first map, so other item is from second
|
||||
differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (SHAMapItem::pointer (), otherMapItem)));
|
||||
else
|
||||
differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (otherMapItem, SHAMapItem::pointer ())));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
|
||||
emptyBranch = true;
|
||||
}
|
||||
|
||||
if (emptyBranch || (item->getTag () != otherMapItem->getTag ()))
|
||||
{
|
||||
// unmatched
|
||||
if (isFirstMap)
|
||||
differences.insert (std::make_pair (item->getTag (), std::make_pair (item, SHAMapItem::pointer ())));
|
||||
else
|
||||
differences.insert (std::make_pair (item->getTag (), std::make_pair (SHAMapItem::pointer (), item)));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->peekData () != otherMapItem->peekData ())
|
||||
{
|
||||
// non-matching items
|
||||
if (isFirstMap) differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (item, otherMapItem)));
|
||||
else differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (otherMapItem, item)));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
emptyBranch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!emptyBranch)
|
||||
{
|
||||
// otherMapItem was unmatched, must add
|
||||
if (isFirstMap) // this is first map, so other item is from second
|
||||
differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (SHAMapItem::pointer (), otherMapItem)));
|
||||
else
|
||||
differences.insert (std::make_pair (otherMapItem->getTag (),
|
||||
std::make_pair (otherMapItem, SHAMapItem::pointer ())));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHAMap::compare(SHAMap::ref otherMap, Delta& differences, int maxCount)
|
||||
{ // compare two hash trees, add up to maxCount differences to the difference table
|
||||
// return value: true=complete table of differences given, false=too many differences
|
||||
// throws on corrupt tables or missing nodes
|
||||
// CAUTION: otherMap is not locked and must be immutable
|
||||
|
||||
assert(isValid() && otherMap && otherMap->isValid());
|
||||
|
||||
std::stack<SHAMapDeltaNode> nodeStack; // track nodes we've pushed
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
|
||||
if (getHash() == otherMap->getHash())
|
||||
return true;
|
||||
|
||||
nodeStack.push(SHAMapDeltaNode(SHAMapNode(), getHash(), otherMap->getHash()));
|
||||
while (!nodeStack.empty())
|
||||
{
|
||||
SHAMapDeltaNode dNode(nodeStack.top());
|
||||
nodeStack.pop();
|
||||
|
||||
SHAMapTreeNode* ourNode = getNodePointer(dNode.mNodeID, dNode.mOurHash);
|
||||
SHAMapTreeNode* otherNode = otherMap->getNodePointer(dNode.mNodeID, dNode.mOtherHash);
|
||||
if (!ourNode || !otherNode)
|
||||
{
|
||||
assert(false);
|
||||
throw SHAMapMissingNode(mType, dNode.mNodeID, uint256());
|
||||
}
|
||||
|
||||
if (ourNode->isLeaf() && otherNode->isLeaf())
|
||||
{ // two leaves
|
||||
if (ourNode->getTag() == otherNode->getTag())
|
||||
{
|
||||
if (ourNode->peekData() != otherNode->peekData())
|
||||
{
|
||||
differences.insert(std::make_pair(ourNode->getTag(),
|
||||
std::make_pair(ourNode->getItem(), otherNode->getItem())));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
differences.insert(std::make_pair(ourNode->getTag(),
|
||||
std::make_pair(ourNode->getItem(), SHAMapItem::pointer())));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
differences.insert(std::make_pair(otherNode->getTag(),
|
||||
std::make_pair(SHAMapItem::pointer(), otherNode->getItem())));
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ourNode->isInner() && otherNode->isLeaf())
|
||||
{
|
||||
if (!walkBranch(ourNode, otherNode->getItem(), true, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isLeaf() && otherNode->isInner())
|
||||
{
|
||||
if (!otherMap->walkBranch(otherNode, ourNode->getItem(), false, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isInner() && otherNode->isInner())
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if (ourNode->getChildHash(i) != otherNode->getChildHash(i))
|
||||
{
|
||||
if (otherNode->isEmptyBranch(i))
|
||||
{ // We have a branch, the other tree does not
|
||||
SHAMapTreeNode* iNode = getNodePointer(ourNode->getChildNodeID(i), ourNode->getChildHash(i));
|
||||
if (!walkBranch(iNode, SHAMapItem::pointer(), true, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isEmptyBranch(i))
|
||||
{ // The other tree has a branch, we do not
|
||||
SHAMapTreeNode* iNode =
|
||||
otherMap->getNodePointer(otherNode->getChildNodeID(i), otherNode->getChildHash(i));
|
||||
if (!otherMap->walkBranch(iNode, SHAMapItem::pointer(), false, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else // The two trees have different non-empty branches
|
||||
nodeStack.push(SHAMapDeltaNode(ourNode->getChildNodeID(i),
|
||||
ourNode->getChildHash(i), otherNode->getChildHash(i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SHAMap::walkMap(std::vector<SHAMapMissingNode>& missingNodes, int maxMissing)
|
||||
bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
|
||||
{
|
||||
std::stack<SHAMapTreeNode::pointer> nodeStack;
|
||||
// compare two hash trees, add up to maxCount differences to the difference table
|
||||
// return value: true=complete table of differences given, false=too many differences
|
||||
// throws on corrupt tables or missing nodes
|
||||
// CAUTION: otherMap is not locked and must be immutable
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
assert (isValid () && otherMap && otherMap->isValid ());
|
||||
|
||||
if (!root->isInner()) // root is only node, and we have it
|
||||
return;
|
||||
std::stack<SHAMapDeltaNode> nodeStack; // track nodes we've pushed
|
||||
|
||||
nodeStack.push(root);
|
||||
boost::recursive_mutex::scoped_lock sl (mLock);
|
||||
|
||||
while (!nodeStack.empty())
|
||||
{
|
||||
SHAMapTreeNode::pointer node = nodeStack.top();
|
||||
nodeStack.pop();
|
||||
if (getHash () == otherMap->getHash ())
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if (!node->isEmptyBranch(i))
|
||||
{
|
||||
try
|
||||
{
|
||||
SHAMapTreeNode::pointer d = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
|
||||
if (d->isInner())
|
||||
nodeStack.push(d);
|
||||
}
|
||||
catch (SHAMapMissingNode& n)
|
||||
{
|
||||
missingNodes.push_back(n);
|
||||
if (--maxMissing <= 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeStack.push (SHAMapDeltaNode (SHAMapNode (), getHash (), otherMap->getHash ()));
|
||||
|
||||
while (!nodeStack.empty ())
|
||||
{
|
||||
SHAMapDeltaNode dNode (nodeStack.top ());
|
||||
nodeStack.pop ();
|
||||
|
||||
SHAMapTreeNode* ourNode = getNodePointer (dNode.mNodeID, dNode.mOurHash);
|
||||
SHAMapTreeNode* otherNode = otherMap->getNodePointer (dNode.mNodeID, dNode.mOtherHash);
|
||||
|
||||
if (!ourNode || !otherNode)
|
||||
{
|
||||
assert (false);
|
||||
throw SHAMapMissingNode (mType, dNode.mNodeID, uint256 ());
|
||||
}
|
||||
|
||||
if (ourNode->isLeaf () && otherNode->isLeaf ())
|
||||
{
|
||||
// two leaves
|
||||
if (ourNode->getTag () == otherNode->getTag ())
|
||||
{
|
||||
if (ourNode->peekData () != otherNode->peekData ())
|
||||
{
|
||||
differences.insert (std::make_pair (ourNode->getTag (),
|
||||
std::make_pair (ourNode->getItem (), otherNode->getItem ())));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
differences.insert (std::make_pair (ourNode->getTag (),
|
||||
std::make_pair (ourNode->getItem (), SHAMapItem::pointer ())));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
|
||||
differences.insert (std::make_pair (otherNode->getTag (),
|
||||
std::make_pair (SHAMapItem::pointer (), otherNode->getItem ())));
|
||||
|
||||
if (--maxCount <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ourNode->isInner () && otherNode->isLeaf ())
|
||||
{
|
||||
if (!walkBranch (ourNode, otherNode->getItem (), true, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isLeaf () && otherNode->isInner ())
|
||||
{
|
||||
if (!otherMap->walkBranch (otherNode, ourNode->getItem (), false, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isInner () && otherNode->isInner ())
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if (ourNode->getChildHash (i) != otherNode->getChildHash (i))
|
||||
{
|
||||
if (otherNode->isEmptyBranch (i))
|
||||
{
|
||||
// We have a branch, the other tree does not
|
||||
SHAMapTreeNode* iNode = getNodePointer (ourNode->getChildNodeID (i), ourNode->getChildHash (i));
|
||||
|
||||
if (!walkBranch (iNode, SHAMapItem::pointer (), true, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else if (ourNode->isEmptyBranch (i))
|
||||
{
|
||||
// The other tree has a branch, we do not
|
||||
SHAMapTreeNode* iNode =
|
||||
otherMap->getNodePointer (otherNode->getChildNodeID (i), otherNode->getChildHash (i));
|
||||
|
||||
if (!otherMap->walkBranch (iNode, SHAMapItem::pointer (), false, differences, maxCount))
|
||||
return false;
|
||||
}
|
||||
else // The two trees have different non-empty branches
|
||||
nodeStack.push (SHAMapDeltaNode (ourNode->getChildNodeID (i),
|
||||
ourNode->getChildHash (i), otherNode->getChildHash (i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
assert (false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SHAMap::walkMap (std::vector<SHAMapMissingNode>& missingNodes, int maxMissing)
|
||||
{
|
||||
std::stack<SHAMapTreeNode::pointer> nodeStack;
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl (mLock);
|
||||
|
||||
if (!root->isInner ()) // root is only node, and we have it
|
||||
return;
|
||||
|
||||
nodeStack.push (root);
|
||||
|
||||
while (!nodeStack.empty ())
|
||||
{
|
||||
SHAMapTreeNode::pointer node = nodeStack.top ();
|
||||
nodeStack.pop ();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
if (!node->isEmptyBranch (i))
|
||||
{
|
||||
try
|
||||
{
|
||||
SHAMapTreeNode::pointer d = getNode (node->getChildNodeID (i), node->getChildHash (i), false);
|
||||
|
||||
if (d->isInner ())
|
||||
nodeStack.push (d);
|
||||
}
|
||||
catch (SHAMapMissingNode& n)
|
||||
{
|
||||
missingNodes.push_back (n);
|
||||
|
||||
if (--maxMissing <= 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user