From 8a5d001e29961de85426a22581aeec218a40e3d2 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 18 Jan 2015 01:20:56 +0300 Subject: [PATCH] Linked list: optimized insertBefore(), elaborated docs --- libuavcan/include/uavcan/util/linked_list.hpp | 17 +++++++++++++---- libuavcan/test/util/linked_list.cpp | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libuavcan/include/uavcan/util/linked_list.hpp b/libuavcan/include/uavcan/util/linked_list.hpp index c907a28bb7..963cee9f02 100644 --- a/libuavcan/include/uavcan/util/linked_list.hpp +++ b/libuavcan/include/uavcan/util/linked_list.hpp @@ -57,19 +57,22 @@ public: unsigned getLength() const; /** - * Complexity: O(N) (calls remove()) + * Inserts the node to the beginning of the list. + * If the node is already present in the list, it will be relocated to the beginning. + * Complexity: O(N) */ void insert(T* node); /** - * Inserts the node immediately before the node B where - * predicate(B) -> true. + * Inserts the node immediately before the node X where predicate(X) returns true. + * If the node is already present in the list, it can be relocated to a new position. * Complexity: O(2N) (calls remove()) */ template void insertBefore(T* node, Predicate predicate); /** + * Removes only the first occurence of the node. * Complexity: O(N) */ void remove(const T* node); @@ -107,11 +110,17 @@ template void LinkedListRoot::insertBefore(T* node, Predicate predicate) { UAVCAN_ASSERT(node); + if (node == NULL) + { + return; + } + remove(node); if (root_ == NULL || predicate(root_)) { - insert(node); + node->setNextListNode(root_); + root_ = node; } else { diff --git a/libuavcan/test/util/linked_list.cpp b/libuavcan/test/util/linked_list.cpp index 392215a934..96c8be0e6d 100644 --- a/libuavcan/test/util/linked_list.cpp +++ b/libuavcan/test/util/linked_list.cpp @@ -104,11 +104,27 @@ TEST(LinkedList, Sorting) uavcan::LinkedListRoot root; ListItem items[] = {0, 1, 2, 3, 4, 5}; + EXPECT_EQ(0, root.getLength()); + items[2].insort(root); + EXPECT_EQ(1, root.getLength()); + + items[2].insort(root); // Making sure the duplicate will be removed + EXPECT_EQ(1, root.getLength()); + items[3].insort(root); + items[0].insort(root); + items[4].insort(root); + EXPECT_EQ(4, root.getLength()); + items[1].insort(root); + EXPECT_EQ(5, root.getLength()); + + items[1].insort(root); // Another duplicate + EXPECT_EQ(5, root.getLength()); + items[5].insort(root); EXPECT_EQ(6, root.getLength());