Skip to content

Commit d6035d0

Browse files
committed
#3 allow removal from btree list to complete the interface
1 parent 5e5e796 commit d6035d0

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

src/SimpleCollections.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <malloc.h>
1010
#endif
1111
#include "SimpleCollections.h"
12+
#include <IoLogging.h>
1213

1314
using namespace ioaTreeInternal;
1415

@@ -51,6 +52,31 @@ bool BtreeStorage::add(const void *newItem) {
5152
return true;
5253
}
5354

55+
bool BtreeStorage::removeByKey(uint32_t key) {
56+
for(bsize_t i = 0; i<currentSize; ++i) {
57+
if(keyAccessor(memoryOf(binTree, i)) == key) {
58+
removeIndex(i);
59+
return true;
60+
}
61+
}
62+
return false;
63+
}
64+
65+
void BtreeStorage::removeIndex(bsize_t index) {
66+
// given the insert position, work out the number of items to move
67+
int amtToMove = (currentSize - index) - 1;
68+
69+
serdebugF4("remove ", amtToMove, index, currentCapacity);
70+
71+
// move the instances in reverse order using their assignment operator.
72+
if(amtToMove > 0) {
73+
for (bsize_t i = index; i < index + amtToMove; ++i) {
74+
copier(memoryOf(binTree, i), memoryOf(binTree, i + 1));
75+
}
76+
}
77+
currentSize--;
78+
}
79+
5480
/**
5581
* Check the capacity of the list, increasing the size if needed. This is normally called before an add operation
5682
* to ensure there will be space to add another item.

src/SimpleCollections.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ namespace ioaTreeInternal {
6464

6565
bool add(const void *newItem);
6666

67+
bool removeByKey(uint32_t key);
68+
69+
void removeIndex(bsize_t index);
70+
6771
bsize_t nearestLocation(uint32_t key);
6872

6973
void *getByKey(uint32_t key);
@@ -145,6 +149,19 @@ template<class K, class V> class BtreeList {
145149
*/
146150
V* getByKey(K key) { return reinterpret_cast<V*>(treeStorage.getByKey(key)); };
147151

152+
/**
153+
* Remove an item using the key it was added with
154+
* @param key the key to remove
155+
* @return true if successful otherwise false.
156+
*/
157+
bool removeByKey(K key) { return treeStorage.removeByKey(key); }
158+
159+
/**
160+
* Remove an item by index in the underlying array
161+
* @param index the index in the array
162+
*/
163+
void removeIndex(bsize_t index) { treeStorage.removeIndex(index); }
164+
148165
/**
149166
* gets the nearest location to the key, this is an in-exact method in that it gives the exact match if available
150167
* or otherwise the nearest one that is lower.

tests/collectionTests/SimpleCollectionsTest.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,72 @@ test(testAddingWithSortAndResizeBy5) {
181181
assertEqual(btreeList.getByKey(9)->getItem(), 108);
182182

183183
}
184+
185+
class NumericStorageItem {
186+
private:
187+
uint32_t item;
188+
189+
public:
190+
NumericStorageItem() : item(0xffffffff) {}
191+
explicit NumericStorageItem(uint32_t value) : item(value) {}
192+
NumericStorageItem(const NumericStorageItem& other) = default;
193+
NumericStorageItem& operator= (const NumericStorageItem& other) = default;
194+
uint32_t getKey() const { return item; }
195+
};
196+
197+
void printArray(const NumericStorageItem* list, int size) {
198+
char sz[160];
199+
strcpy(sz, "array: ");
200+
for(int i=0;i<size;i++) {
201+
char intBuf[10];
202+
itoa((int)(list[i].getKey()), intBuf, 10);
203+
strcat(sz, intBuf);
204+
strcat(sz, " ");
205+
}
206+
serdebug(sz);
207+
}
208+
209+
210+
test(testAddingThenRemovingThenAddingItems) {
211+
BtreeList<uint32_t, NumericStorageItem> myList;
212+
213+
for(int i=0;i<20;i++) {
214+
myList.add(NumericStorageItem(i + 100));
215+
}
216+
217+
// should have 20 items now
218+
assertEqual(myList.count(), bsize_t(20));
219+
220+
// remove key 102
221+
assertTrue(myList.removeByKey(102));
222+
assertFalse(myList.removeByKey(10002));
223+
224+
printArray(myList.items(), myList.count());
225+
226+
// should have 19 items
227+
assertEqual(myList.count(), bsize_t(19));
228+
229+
// ensure that only 102 was removed
230+
assertTrue(myList.getByKey(102) == nullptr);
231+
assertTrue(myList.getByKey(103) != nullptr);
232+
assertTrue(myList.getByKey(101) != nullptr);
233+
234+
// put 102 back
235+
myList.add(NumericStorageItem(102));
236+
237+
printArray(myList.items(), myList.count());
238+
239+
for(int i=0;i<20;i++) {
240+
auto entry = myList.itemAtIndex(i);
241+
assertEqual(entry->getKey(), uint32_t(i + 100));
242+
}
243+
244+
// now test removing the edge cases, IE head and tail of list
245+
myList.removeIndex(0);
246+
myList.removeIndex(19);
247+
printArray(myList.items(), myList.count());
248+
249+
assertEqual(myList.count(), bsize_t(18));
250+
assertTrue(myList.getByKey(100) == nullptr);
251+
assertTrue(myList.getByKey(119) == nullptr);
252+
}

0 commit comments

Comments
 (0)