@@ -89,6 +89,7 @@ class BVSparse
8989// Data
9090public:
9191 Field (BVSparseNode*, TAllocator) head;
92+ Field (BVSparseNode*, TAllocator) lastFoundIndex;
9293
9394private:
9495 FieldNoBarrier (TAllocator*) alloc;
@@ -322,7 +323,8 @@ const SparseBVUnit BVSparse<TAllocator>::s_EmptyUnit(0);
322323template <class TAllocator >
323324BVSparse<TAllocator>::BVSparse(TAllocator* allocator) :
324325 alloc (allocator),
325- head(nullptr )
326+ head(nullptr ),
327+ lastFoundIndex(nullptr )
326328{
327329 this ->lastUsedNodePrevNextField = &this ->head ;
328330}
@@ -414,7 +416,10 @@ BVSparse<TAllocator>::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator)
414416 const BVIndex searchIndex = SparseBVUnit::Floor (i);
415417
416418 Field (BVSparseNode*, TAllocator) const * prevNextField = &this ->head ;
417- const BVSparseNode * curNode = *prevNextField;
419+ Field (BVSparseNode*, TAllocator) const * prevLastField = &this ->lastFoundIndex ;
420+
421+ const BVSparseNode * curNode = *prevNextField,
422+ * lastNode = *prevLastField;
418423 if (curNode != nullptr )
419424 {
420425 if (curNode->startIndex == searchIndex)
@@ -423,6 +428,21 @@ BVSparse<TAllocator>::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator)
423428 return curNode;
424429 }
425430
431+ if (lastNode && lastNode->startIndex != curNode->startIndex )
432+ {
433+ if (lastNode->startIndex == searchIndex)
434+ {
435+ *prevNextFieldOut = prevLastField;
436+ return lastNode;
437+ }
438+
439+ if (lastNode->startIndex < searchIndex)
440+ {
441+ prevNextField = &this ->lastFoundIndex ;
442+ curNode = this ->lastFoundIndex ;
443+ }
444+ }
445+
426446 if (curNode->startIndex > searchIndex)
427447 {
428448 prevNextField = &this ->head ;
@@ -440,6 +460,8 @@ BVSparse<TAllocator>::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator)
440460 prevNextField = &curNode->next ;
441461 }
442462
463+ const_cast <BVSparse<TAllocator>*>(this )->lastFoundIndex = *prevNextField;
464+
443465 if (curNode && searchIndex == curNode->startIndex )
444466 {
445467 *prevNextFieldOut = prevNextField;
@@ -486,6 +508,7 @@ template <class TAllocator>
486508BVSparseNode<TAllocator> *
487509BVSparse<TAllocator>::DeleteNode(BVSparseNode *node, bool bResetLastUsed)
488510{
511+ this ->lastFoundIndex = nullptr ;
489512 BVSparseNode *next = node->next ;
490513 QueueInFreeList (node);
491514
@@ -563,6 +586,7 @@ BVSparse<TAllocator>::ClearAll()
563586 QueueInFreeList (node);
564587 }
565588 this ->head = nullptr ;
589+ this ->lastFoundIndex = nullptr ;
566590 this ->lastUsedNodePrevNextField = &this ->head ;
567591}
568592
@@ -902,6 +926,7 @@ BVSparse<TAllocator>::CopyFromNode(const ::BVSparseNode<TSrcAllocator> * node2)
902926{
903927 BVSparseNode * node1 = this ->head ;
904928 Field (BVSparseNode*, TAllocator)* prevNextField = &this ->head ;
929+ this ->lastFoundIndex = nullptr ;
905930
906931 while (node1 != nullptr && node2 != nullptr )
907932 {
0 commit comments