First part of fetch acceleration changes. Includes a bugfix that I'll push to master.

This commit is contained in:
JoelKatz
2013-04-21 12:44:21 -07:00
parent b993c6ee32
commit 79ec8e6070
11 changed files with 272 additions and 28 deletions

View File

@@ -571,6 +571,95 @@ std::ostream& operator<<(std::ostream& out, const SHAMapMissingNode& mn)
return out;
}
SHAMapIterator::SHAMapIterator(SHAMap& map, bool returnInner, bool returnLeaf) :
mMap(map), mInner(returnInner), mLeaf(returnLeaf), mLock(false)
{
mStack.push(stack_t(mMap.root.get(), 0));
}
SHAMapIterator::~SHAMapIterator()
{
if (mLock)
{
while (!mStack.empty())
mStack.pop();
mMap.mLock.unlock();
}
}
bool SHAMapIterator::lock()
{
if (mLock)
return false;
mMap.mLock.lock();
mLock = true;
return true;
}
bool SHAMapIterator::unlock()
{
if (!mLock)
return false;
mMap.mLock.unlock();
mLock = false;
return true;
}
void SHAMapIterator::reset()
{
while (!mStack.empty())
mStack.pop();
mStack.push(stack_t(mMap.root.get(), 0));
}
SHAMapTreeNode* SHAMapIterator::getNext()
{
if (mStack.empty())
return NULL;
stack_t& top = mStack.top();
if (top.first->isLeaf())
{ // special case, map has only one leaf
SHAMapTreeNode* ret = mLeaf ? top.first : NULL;
mStack.pop();
return ret;
}
while (1)
{
while (top.second < 16)
{ // continue where we left off
if (top.first->isEmptyBranch(top.second))
++top.second;
else
{
SHAMapTreeNode* next = mMap.getNodePointer(
top.first->getChildNodeID(top.second), top.first->getChildHash(top.second));
++top.second;
if (next->isLeaf())
{
if (mLeaf)
return next;
}
else
{
mStack.push(stack_t(next, 0));
top = mStack.top();
}
}
}
if (top.second == 16)
{ // we ran off the end of an inner node
SHAMapTreeNode* ret = top.first;
mStack.pop();
if (mInner)
return ret;
if (mStack.empty()) // ran off the end of the root
return NULL;
top = mStack.top();
}
}
}
// vim:ts=4