This commit is contained in:
JoelKatz
2012-05-07 16:27:18 -07:00
parent a626706638
commit 133ee09297
2 changed files with 89 additions and 89 deletions

View File

@@ -11,9 +11,9 @@
SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying) SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying)
{ {
root=boost::make_shared<SHAMapTreeNode>(SHAMapNode(0, uint256()), mSeq); root = boost::make_shared<SHAMapTreeNode>(SHAMapNode(0, uint256()), mSeq);
root->makeInner(); root->makeInner();
mTNByID[*root]=root; mTNByID[*root] = root;
} }
std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool include_nonmatching_leaf) std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool include_nonmatching_leaf)
@@ -21,27 +21,27 @@ std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool inc
// Walk the tree as far as possible to the specified identifier // Walk the tree as far as possible to the specified identifier
// produce a stack of nodes along the way, with the terminal node at the top // produce a stack of nodes along the way, with the terminal node at the top
std::stack<SHAMapTreeNode::pointer> stack; std::stack<SHAMapTreeNode::pointer> stack;
SHAMapTreeNode::pointer node=root; SHAMapTreeNode::pointer node = root;
while(!node->isLeaf()) while (!node->isLeaf())
{ {
stack.push(node); stack.push(node);
int branch=node->selectBranch(id); int branch = node->selectBranch(id);
assert(branch>=0); assert(branch >= 0);
uint256 hash=node->getChildHash(branch); uint256 hash = node->getChildHash(branch);
if(hash.isZero()) return stack; if (hash.isZero()) return stack;
node=getNode(node->getChildNodeID(branch), hash, false); node = getNode(node->getChildNodeID(branch), hash, false);
if(!node) if (!node)
{ {
if(isSynching()) return stack; if (isSynching()) return stack;
throw SHAMapException(MissingNode); throw SHAMapException(MissingNode);
} }
} }
if(include_nonmatching_leaf || (node->peekItem()->getTag()==id)) if (include_nonmatching_leaf || (node->peekItem()->getTag() == id))
stack.push(node); stack.push(node);
return stack; return stack;
@@ -51,20 +51,20 @@ void SHAMap::dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256&
{ // walk the tree up from through the inner nodes to the root { // walk the tree up from through the inner nodes to the root
// update linking hashes and add nodes to dirty list // update linking hashes and add nodes to dirty list
assert(mState!=Synching && mState!=Immutable); assert((mState != Synching) && (mState != Immutable));
while(!stack.empty()) while (!stack.empty())
{ {
SHAMapTreeNode::pointer node=stack.top(); SHAMapTreeNode::pointer node=stack.top();
stack.pop(); stack.pop();
assert(node->isInnerNode()); assert(node->isInnerNode());
int branch=node->selectBranch(target); int branch = node->selectBranch(target);
assert(branch>=0); assert(branch >= 0);
returnNode(node, true); returnNode(node, true);
if(!node->setChildHash(branch, prevHash)) if (!node->setChildHash(branch, prevHash))
{ {
std::cerr << "dirtyUp terminates early" << std::endl; std::cerr << "dirtyUp terminates early" << std::endl;
assert(false); assert(false);
@@ -73,15 +73,15 @@ void SHAMap::dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256&
#ifdef ST_DEBUG #ifdef ST_DEBUG
std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash.GetHex() << std::endl; std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash.GetHex() << std::endl;
#endif #endif
prevHash=node->getNodeHash(); prevHash = node->getNodeHash();
assert(prevHash.isNonZero()); assert(prevHash.isNonZero());
} }
} }
SHAMapTreeNode::pointer SHAMap::checkCacheNode(const SHAMapNode& iNode) SHAMapTreeNode::pointer SHAMap::checkCacheNode(const SHAMapNode& iNode)
{ {
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it=mTNByID.find(iNode); boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = mTNByID.find(iNode);
if(it==mTNByID.end()) return SHAMapTreeNode::pointer(); if (it == mTNByID.end()) return SHAMapTreeNode::pointer();
return it->second; return it->second;
} }
@@ -90,27 +90,27 @@ SHAMapTreeNode::pointer SHAMap::walkTo(const uint256& id, bool modify)
SHAMapTreeNode::pointer inNode=root; SHAMapTreeNode::pointer inNode=root;
while(!inNode->isLeaf()) while (!inNode->isLeaf())
{ {
int branch=inNode->selectBranch(id); int branch = inNode->selectBranch(id);
if(inNode->isEmptyBranch(branch)) return inNode; if (inNode->isEmptyBranch(branch)) return inNode;
uint256 childHash=inNode->getChildHash(branch); uint256 childHash = inNode->getChildHash(branch);
if(childHash.isZero()) return inNode; if (childHash.isZero()) return inNode;
SHAMapTreeNode::pointer nextNode=getNode(inNode->getChildNodeID(branch), childHash, false); SHAMapTreeNode::pointer nextNode = getNode(inNode->getChildNodeID(branch), childHash, false);
if(!nextNode) throw SHAMapException(MissingNode); if (!nextNode) throw SHAMapException(MissingNode);
inNode=nextNode; inNode = nextNode;
} }
if(modify) returnNode(inNode, true); if (modify) returnNode(inNode, true);
return inNode; return inNode;
} }
SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& hash, bool modify) SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& hash, bool modify)
{ // retrieve a node whose node hash is known { // retrieve a node whose node hash is known
SHAMapTreeNode::pointer node=checkCacheNode(id); SHAMapTreeNode::pointer node = checkCacheNode(id);
if(node) if (node)
{ {
if(node->getNodeHash()!=hash) if (node->getNodeHash()!=hash)
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "Attempt to get node, hash not in tree" << std::endl; std::cerr << "Attempt to get node, hash not in tree" << std::endl;
@@ -128,10 +128,10 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& has
std::vector<unsigned char> nodeData; std::vector<unsigned char> nodeData;
if(!fetchNode(hash, nodeData)) return SHAMapTreeNode::pointer(); if(!fetchNode(hash, nodeData)) return SHAMapTreeNode::pointer();
node=boost::make_shared<SHAMapTreeNode>(id, nodeData, mSeq); node = boost::make_shared<SHAMapTreeNode>(id, nodeData, mSeq);
if(node->getNodeHash()!=hash) throw SHAMapException(InvalidNode); if (node->getNodeHash() != hash) throw SHAMapException(InvalidNode);
if(!mTNByID.insert(std::make_pair(id, node)).second) if (!mTNByID.insert(std::make_pair(id, node)).second)
assert(false); assert(false);
return node; return node;
} }
@@ -139,15 +139,15 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& has
void SHAMap::returnNode(SHAMapTreeNode::pointer& node, bool modify) void SHAMap::returnNode(SHAMapTreeNode::pointer& node, bool modify)
{ // make sure the node is suitable for the intended operation (copy on write) { // make sure the node is suitable for the intended operation (copy on write)
assert(node->isValid()); assert(node->isValid());
if(node && modify && (node->getSeq()!=mSeq)) if (node && modify && (node->getSeq()!=mSeq))
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "returnNode COW" << std::endl; std::cerr << "returnNode COW" << std::endl;
#endif #endif
if(mDirtyNodes) (*mDirtyNodes)[*node]=node; if (mDirtyNodes) (*mDirtyNodes)[*node] = node;
node=boost::make_shared<SHAMapTreeNode>(*node, mSeq); node = boost::make_shared<SHAMapTreeNode>(*node, mSeq);
assert(node->isValid()); assert(node->isValid());
mTNByID[*node]=node; mTNByID[*node] = node;
} }
} }
@@ -163,24 +163,24 @@ SHAMapItem::pointer SHAMap::firstBelow(SHAMapTreeNode::pointer node)
#endif #endif
do do
{ // Walk down the tree { // Walk down the tree
if(node->hasItem()) return node->peekItem(); if (node->hasItem()) return node->peekItem();
bool foundNode=false; bool foundNode = false;
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
#ifdef ST_DEBUG #ifdef ST_DEBUG
std::cerr << " FB: node " << node->getString() << std::endl; std::cerr << " FB: node " << node->getString() << std::endl;
std::cerr << " has non-empty branch " << i << " : " << std::cerr << " has non-empty branch " << i << " : " <<
node->getChildNodeID(i).getString() << ", " << node->getChildHash(i).GetHex() << std::endl; node->getChildNodeID(i).getString() << ", " << node->getChildHash(i).GetHex() << std::endl;
#endif #endif
node=getNode(node->getChildNodeID(i), node->getChildHash(i), false); node = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!node) throw SHAMapException(MissingNode); if (!node) throw SHAMapException(MissingNode);
foundNode=true; foundNode = true;
break; break;
} }
if(!foundNode) return SHAMapItem::pointer(); if (!foundNode) return SHAMapItem::pointer();
} while(1); } while (1);
} }
SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node) SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node)
@@ -191,46 +191,46 @@ SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node)
do do
{ // Walk down the tree { // Walk down the tree
if(node->hasItem()) return node->peekItem(); if (node->hasItem()) return node->peekItem();
bool foundNode=false; bool foundNode = false;
for(int i=15; i>=0; i++) for (int i = 15; i >= 0; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
node=getNode(node->getChildNodeID(i), node->getChildHash(i), false); node = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!node) throw SHAMapException(MissingNode); if (!node) throw SHAMapException(MissingNode);
foundNode=true; foundNode = true;
break; break;
} }
if(!foundNode) return SHAMapItem::pointer(); if (!foundNode) return SHAMapItem::pointer();
} while(1); } while (1);
} }
SHAMapItem::pointer SHAMap::onlyBelow(SHAMapTreeNode::pointer node) SHAMapItem::pointer SHAMap::onlyBelow(SHAMapTreeNode::pointer node)
{ {
// If there is only one item below this node, return it // If there is only one item below this node, return it
bool found; bool found;
while(!node->isLeaf()) while (!node->isLeaf())
{ {
found=false; found = false;
SHAMapTreeNode::pointer nextNode; SHAMapTreeNode::pointer nextNode;
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
if(found) return SHAMapItem::pointer(); // two leaves below if( found) return SHAMapItem::pointer(); // two leaves below
nextNode=getNode(node->getChildNodeID(i), node->getChildHash(i), false); nextNode = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!nextNode) throw SHAMapException(MissingNode); if (!nextNode) throw SHAMapException(MissingNode);
found=true; found = true;
} }
if(!found) if (!found)
{ {
std::cerr << node->getString() << std::endl; std::cerr << node->getString() << std::endl;
assert(false); assert(false);
return SHAMapItem::pointer(); return SHAMapItem::pointer();
} }
node=nextNode; node = nextNode;
} }
assert(node->hasItem()); assert(node->hasItem());
return node->peekItem(); return node->peekItem();
@@ -618,11 +618,11 @@ void SHAMap::dump(bool hash)
} }
static std::vector<unsigned char>IntToVUC(int i) static std::vector<unsigned char>IntToVUC(int v)
{ {
std::vector<unsigned char> vuc; std::vector<unsigned char> vuc;
for(int i=0; i<32; i++) for (int i = 0; i < 32; ++i)
vuc.push_back((unsigned char) i); vuc.push_back(static_cast<unsigned char>(v));
return vuc; return vuc;
} }

View File

@@ -40,14 +40,14 @@ public:
SHAMapNode(int depth, const uint256& hash); SHAMapNode(int depth, const uint256& hash);
int getDepth() const { return mDepth; } int getDepth() const { return mDepth; }
const uint256& getNodeID() const { return mNodeID; } const uint256& getNodeID() const { return mNodeID; }
bool isValid() const { return (mDepth>=0) && (mDepth<64); } bool isValid() const { return (mDepth >= 0) && (mDepth < 64); }
virtual bool isPopulated() const { return false; } virtual bool isPopulated() const { return false; }
SHAMapNode getParentNodeID() const SHAMapNode getParentNodeID() const
{ {
assert(mDepth); assert(mDepth);
return SHAMapNode(mDepth-1, mNodeID); return SHAMapNode(mDepth - 1, mNodeID);
} }
SHAMapNode getChildNodeID(int m) const; SHAMapNode getChildNodeID(int m) const;
int selectBranch(const uint256& hash) const; int selectBranch(const uint256& hash) const;
@@ -108,18 +108,18 @@ public:
void updateData(const std::vector<unsigned char>& data) { mData=data; } void updateData(const std::vector<unsigned char>& data) { mData=data; }
bool operator<(const SHAMapItem& i) const { return mTag<i.mTag; } bool operator<(const SHAMapItem& i) const { return mTag < i.mTag; }
bool operator>(const SHAMapItem& i) const { return mTag>i.mTag; } bool operator>(const SHAMapItem& i) const { return mTag > i.mTag; }
bool operator==(const SHAMapItem& i) const { return mTag==i.mTag; } bool operator==(const SHAMapItem& i) const { return mTag == i.mTag; }
bool operator!=(const SHAMapItem& i) const { return mTag!=i.mTag; } bool operator!=(const SHAMapItem& i) const { return mTag != i.mTag; }
bool operator<=(const SHAMapItem& i) const { return mTag<=i.mTag; } bool operator<=(const SHAMapItem& i) const { return mTag <= i.mTag; }
bool operator>=(const SHAMapItem& i) const { return mTag>=i.mTag; } bool operator>=(const SHAMapItem& i) const { return mTag >= i.mTag; }
bool operator<(const uint256& i) const { return mTag<i; } bool operator<(const uint256& i) const { return mTag < i; }
bool operator>(const uint256& i) const { return mTag>i; } bool operator>(const uint256& i) const { return mTag > i; }
bool operator==(const uint256& i) const { return mTag==i; } bool operator==(const uint256& i) const { return mTag == i; }
bool operator!=(const uint256& i) const { return mTag!=i; } bool operator!=(const uint256& i) const { return mTag != i; }
bool operator<=(const uint256& i) const { return mTag<=i; } bool operator<=(const uint256& i) const { return mTag <= i; }
bool operator>=(const uint256& i) const { return mTag>=i; } bool operator>=(const uint256& i) const { return mTag >= i; }
virtual void dump(); virtual void dump();
}; };
@@ -132,10 +132,10 @@ public:
enum TNType enum TNType
{ {
tnERROR =0, tnERROR = 0,
tnINNER =1, tnINNER = 1,
tnTRANSACTION =2, tnTRANSACTION = 2,
tnACCOUNT_STATE =3 tnACCOUNT_STATE = 3
}; };
private: private:
@@ -295,7 +295,7 @@ public:
// status functions // status functions
void setImmutable(void) { assert(mState != Invalid); mState = Immutable; } void setImmutable(void) { assert(mState != Invalid); mState = Immutable; }
void clearImmutable(void) { mState = Modifying; } void clearImmutable(void) { mState = Modifying; }
bool isSynching(void) const { return mState == Floating || mState == Synching; } bool isSynching(void) const { return (mState == Floating) || (mState == Synching); }
void setSynching(void) { mState = Synching; } void setSynching(void) { mState = Synching; }
void setFloating(void) { mState = Floating; } void setFloating(void) { mState = Floating; }
void clearSynching(void) { mState = Modifying; } void clearSynching(void) { mState = Modifying; }