Browse Source

IntrusiveQueue add remove method, iterators, and update test

sbg
Daniel Agar 6 years ago
parent
commit
1623de8bd0
  1. 52
      src/include/containers/IntrusiveQueue.hpp
  2. 57
      src/systemcmds/tests/test_IntrusiveQueue.cpp

52
src/include/containers/IntrusiveQueue.hpp

@ -95,6 +95,58 @@ public: @@ -95,6 +95,58 @@ public:
return ret;
}
bool remove(T removeNode)
{
// base case
if (removeNode == _head) {
if (_head->next_intrusive_queue_node() != nullptr) {
_head = _head->next_intrusive_queue_node();
} else {
_head = nullptr;
}
return true;
}
for (T node = _head; node != nullptr; node = node->next_intrusive_queue_node()) {
// is sibling the node to remove?
if (node->next_intrusive_queue_node() == removeNode) {
// replace sibling
if (node->next_intrusive_queue_node() != nullptr) {
node->set_next_intrusive_queue_node(node->next_intrusive_queue_node()->next_intrusive_queue_node());
} else {
node->set_next_intrusive_queue_node(nullptr);
}
return true;
}
}
return false;
}
struct Iterator {
T node;
Iterator(T v) : node(v) {}
operator T() const { return node; }
operator T &() { return node; }
T operator* () const { return node; }
Iterator &operator++ ()
{
if (node) {
node = node->next_intrusive_queue_node();
};
return *this;
}
};
Iterator begin() { return Iterator(_head); }
Iterator end() { return Iterator(nullptr); }
private:
T _head{nullptr};

57
src/systemcmds/tests/test_IntrusiveQueue.cpp

@ -50,6 +50,7 @@ public: @@ -50,6 +50,7 @@ public:
bool test_push();
bool test_pop();
bool test_push_duplicate();
bool test_remove();
};
@ -58,6 +59,7 @@ bool IntrusiveQueueTest::run_tests() @@ -58,6 +59,7 @@ bool IntrusiveQueueTest::run_tests()
ut_run_test(test_push);
ut_run_test(test_pop);
ut_run_test(test_push_duplicate);
ut_run_test(test_remove);
return (_tests_failed == 0);
}
@ -211,4 +213,59 @@ bool IntrusiveQueueTest::test_push_duplicate() @@ -211,4 +213,59 @@ bool IntrusiveQueueTest::test_push_duplicate()
return true;
}
bool IntrusiveQueueTest::test_remove()
{
IntrusiveQueue<testContainer *> q1;
// size should be 0 initially
ut_compare("size initially 0", q1.size(), 0);
ut_assert_true(q1.empty());
// insert 100
for (int i = 0; i < 100; i++) {
testContainer *t = new testContainer();
t->i = i;
q1.push(t);
ut_compare("size increasing with i", q1.size(), i + 1);
ut_assert_true(!q1.empty());
}
// verify full size (100)
ut_assert_true(q1.size() == 100);
// test removing elements
for (int remove_i = 0; remove_i < 100; remove_i++) {
// find node with i == remove_i
for (auto t : q1) {
if (t->i == remove_i) {
ut_assert_true(q1.remove(t));
}
}
// iterate list again to verify removal
for (auto t : q1) {
ut_assert_true(t->i != remove_i);
}
ut_assert_true(q1.size() == 100 - remove_i - 1);
}
// list should now be empty
ut_assert_true(q1.empty());
ut_compare("size 0", q1.size(), 0);
// delete all elements (should be safe on empty list)
while (!q1.empty()) {
q1.pop();
}
// verify list has been cleared
ut_assert_true(q1.empty());
ut_compare("size 0", q1.size(), 0);
return true;
}
ut_declare_test_c(test_IntrusiveQueue, IntrusiveQueueTest)

Loading…
Cancel
Save