Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntrusiveQueue add remove method, iterators, and update test #12246

Merged
merged 3 commits into from
Jun 13, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
IntrusiveQueue add remove method, iterators, and update test
dagar committed Jun 12, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 8a66c8148a6c195a6406744014a250b94aca8cf2
52 changes: 52 additions & 0 deletions src/include/containers/IntrusiveQueue.hpp
Original file line number Diff line number Diff line change
@@ -95,6 +95,58 @@ class IntrusiveQueue
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 changes: 57 additions & 0 deletions src/systemcmds/tests/test_IntrusiveQueue.cpp
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ class IntrusiveQueueTest : public UnitTest
bool test_push();
bool test_pop();
bool test_push_duplicate();
bool test_remove();

};

@@ -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()
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)