From 136a7b45d8202deff5b2b92559f75fae0cecc6da Mon Sep 17 00:00:00 2001 From: Oguz Bastemur Date: Mon, 22 Jan 2018 09:42:06 -0800 Subject: [PATCH] BVSparse: keep 'last found' for fast fromIndex discovery --- lib/Common/DataStructures/SparseBitVector.h | 29 +++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/Common/DataStructures/SparseBitVector.h b/lib/Common/DataStructures/SparseBitVector.h index 134ddff4150..bf12d50ad76 100644 --- a/lib/Common/DataStructures/SparseBitVector.h +++ b/lib/Common/DataStructures/SparseBitVector.h @@ -89,6 +89,7 @@ class BVSparse // Data public: Field(BVSparseNode*, TAllocator) head; + Field(BVSparseNode*, TAllocator) lastFoundIndex; private: FieldNoBarrier(TAllocator*) alloc; @@ -322,7 +323,8 @@ const SparseBVUnit BVSparse::s_EmptyUnit(0); template BVSparse::BVSparse(TAllocator* allocator) : alloc(allocator), - head(nullptr) + head(nullptr), + lastFoundIndex(nullptr) { this->lastUsedNodePrevNextField = &this->head; } @@ -414,7 +416,10 @@ BVSparse::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator) const BVIndex searchIndex = SparseBVUnit::Floor(i); Field(BVSparseNode*, TAllocator) const* prevNextField = &this->head; - const BVSparseNode * curNode = *prevNextField; + Field(BVSparseNode*, TAllocator) const* prevLastField = &this->lastFoundIndex; + + const BVSparseNode * curNode = *prevNextField, + * lastNode = *prevLastField; if (curNode != nullptr) { if (curNode->startIndex == searchIndex) @@ -423,6 +428,21 @@ BVSparse::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator) return curNode; } + if (lastNode && lastNode->startIndex != curNode->startIndex) + { + if (lastNode->startIndex == searchIndex) + { + *prevNextFieldOut = prevLastField; + return lastNode; + } + + if (lastNode->startIndex < searchIndex) + { + prevNextField = &this->lastFoundIndex; + curNode = this->lastFoundIndex; + } + } + if (curNode->startIndex > searchIndex) { prevNextField = &this->head; @@ -440,6 +460,8 @@ BVSparse::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator) prevNextField = &curNode->next; } + const_cast*>(this)->lastFoundIndex = *prevNextField; + if (curNode && searchIndex == curNode->startIndex) { *prevNextFieldOut = prevNextField; @@ -486,6 +508,7 @@ template BVSparseNode * BVSparse::DeleteNode(BVSparseNode *node, bool bResetLastUsed) { + this->lastFoundIndex = nullptr; BVSparseNode *next = node->next; QueueInFreeList(node); @@ -563,6 +586,7 @@ BVSparse::ClearAll() QueueInFreeList(node); } this->head = nullptr; + this->lastFoundIndex = nullptr; this->lastUsedNodePrevNextField = &this->head; } @@ -902,6 +926,7 @@ BVSparse::CopyFromNode(const ::BVSparseNode * node2) { BVSparseNode * node1 = this->head; Field(BVSparseNode*, TAllocator)* prevNextField = &this->head; + this->lastFoundIndex = nullptr; while (node1 != nullptr && node2 != nullptr) {