diff --git a/src/common/classes/sparse_bitmap.h b/src/common/classes/sparse_bitmap.h index 3d2c8b49fb..fb81b2b93c 100644 --- a/src/common/classes/sparse_bitmap.h +++ b/src/common/classes/sparse_bitmap.h @@ -119,15 +119,15 @@ public: const T val_aligned = value & ~(T) (BUNCH_BITS - 1); const BUNCH_T bit_mask = BUNCH_ONE << (value - val_aligned); - if (tree.isPositioned(val_aligned) || tree.locate(val_aligned)) { + + Bucket bucket; + bucket.start_value = val_aligned; + bucket.bits = bit_mask; + if (tree.isPositioned(val_aligned) || !tree.add(bucket)) + { + fb_assert(tree.isPositioned(val_aligned)); tree.current().bits |= bit_mask; } - else { - Bucket bucket; - bucket.start_value = val_aligned; - bucket.bits = bit_mask; - tree.add(bucket); - } } bool clear(T value) { diff --git a/src/common/classes/tree.h b/src/common/classes/tree.h index 7886cc68e4..852970b239 100644 --- a/src/common/classes/tree.h +++ b/src/common/classes/tree.h @@ -175,8 +175,15 @@ public: (level == 0 && ((ItemList*)root)->getCount() == 0); } - bool add(const Value& item); + bool add(const Value& item) {return defaultAccessor.add(item); } + class Accessor; + // If item already exists method sets accessor's current position + // to found item's location and returns false + // If item not exists method will add it to the tree and return true, + // not touching accessor's current position + bool add(const Value& item, Accessor *accessor); + // Remove item. Current position moves to next item after this call. // If next item doesn't exist method returns false bool fastRemove() { return defaultAccessor.fastRemove(); } @@ -338,6 +345,10 @@ public: public: Accessor(BePlusTree* _tree) : curr(NULL), tree(_tree), curPos(0) {} + bool add(const Value& item) { + return tree->add(item, this); + } + // Remove item. Current position moves to next item after this call. // If next item doesn't exist method returns false bool fastRemove() { @@ -564,7 +575,7 @@ private: /************************ BePlusTree implementation ******************/ template -bool BePlusTree::add(const Value& item) +bool BePlusTree::add(const Value& item, Accessor *accessor) { // Finish initialization of the tree if necessary if (!root) root = new (pool->allocate(sizeof(ItemList))) ItemList(); @@ -582,7 +593,13 @@ bool BePlusTree::a ItemList *leaf = (ItemList *)vList; size_t pos; - if (leaf->find(key, pos)) return false; + if (leaf->find(key, pos)) { + if (accessor) { + accessor->curr = leaf; + accessor->curPos = pos; + } + return false; + } if (leaf->getCount() < LeafCount) { leaf->insert(pos, item);