From 9130f00289c6923d3ad08a6e54bcb3c3e22e6844 Mon Sep 17 00:00:00 2001 From: Falk Werner <47070255+falk-werner@users.noreply.github.com> Date: Fri, 26 Apr 2019 20:50:57 +0200 Subject: [PATCH] improves slist implementation (#29) --- lib/webfuse/adapter/impl/session.c | 6 +- lib/webfuse/adapter/impl/session_manager.c | 14 +-- lib/webfuse/core/message_queue.c | 2 +- lib/webfuse/core/slist.c | 58 ++++------ lib/webfuse/core/slist.h | 5 +- test/test_slist.cc | 128 +++++++++++++++++++-- 6 files changed, 151 insertions(+), 62 deletions(-) diff --git a/lib/webfuse/adapter/impl/session.c b/lib/webfuse/adapter/impl/session.c index 241d344..d4f1f56 100644 --- a/lib/webfuse/adapter/impl/session.c +++ b/lib/webfuse/adapter/impl/session.c @@ -65,7 +65,7 @@ struct wf_impl_session * wf_impl_session_create( static void wf_impl_session_dispose_filesystems( struct wf_slist * filesystems) { - struct wf_slist_item * item = filesystems->first; + struct wf_slist_item * item = wf_slist_first(filesystems); while (NULL != item) { struct wf_slist_item * next = item->next; @@ -156,11 +156,11 @@ static struct wf_impl_filesystem * wf_impl_session_get_filesystem( { struct wf_impl_filesystem * result = NULL; - struct wf_slist_item * item = session->filesystems.first; + struct wf_slist_item * item = wf_slist_first(&session->filesystems); while (NULL != item) { struct wf_slist_item * next = item->next; - struct wf_impl_filesystem * filesystem = wf_container_of(session->filesystems.first, struct wf_impl_filesystem, item); + struct wf_impl_filesystem * filesystem = wf_container_of(item, struct wf_impl_filesystem, item); if (wsi == filesystem->wsi) { result = filesystem; diff --git a/lib/webfuse/adapter/impl/session_manager.c b/lib/webfuse/adapter/impl/session_manager.c index c092a48..a48489b 100644 --- a/lib/webfuse/adapter/impl/session_manager.c +++ b/lib/webfuse/adapter/impl/session_manager.c @@ -12,7 +12,7 @@ void wf_impl_session_manager_init( void wf_impl_session_manager_cleanup( struct wf_impl_session_manager * manager) { - struct wf_slist_item * item = manager->sessions.first; + struct wf_slist_item * item = wf_slist_first(&manager->sessions); while (NULL != item) { struct wf_slist_item * next = item->next; @@ -47,7 +47,7 @@ struct wf_impl_session * wf_impl_session_manager_get( { struct wf_impl_session * session = NULL; - struct wf_slist_item * item = manager->sessions.first; + struct wf_slist_item * item = wf_slist_first(&manager->sessions); while (NULL != item) { struct wf_slist_item * next = item->next; @@ -68,11 +68,10 @@ void wf_impl_session_manager_remove( struct wf_impl_session_manager * manager, struct lws * wsi) { - struct wf_slist_item * item = manager->sessions.first; - struct wf_slist_item * prev = NULL; - while (NULL != item) + struct wf_slist_item * prev = &manager->sessions.head; + while (NULL != prev->next) { - struct wf_slist_item * next = item->next; + struct wf_slist_item * item = prev->next; struct wf_impl_session * session = wf_container_of(item, struct wf_impl_session, item); if (wsi == session->wsi) { @@ -81,7 +80,6 @@ void wf_impl_session_manager_remove( break; } - prev = item; - item = next; + prev = prev->next; } } diff --git a/lib/webfuse/core/message_queue.c b/lib/webfuse/core/message_queue.c index b9eb715..af641ff 100644 --- a/lib/webfuse/core/message_queue.c +++ b/lib/webfuse/core/message_queue.c @@ -5,7 +5,7 @@ void wf_message_queue_cleanup( struct wf_slist * queue) { - struct wf_slist_item * item = queue->first; + struct wf_slist_item * item = wf_slist_first(queue); while (NULL != item) { struct wf_slist_item * next = item->next; diff --git a/lib/webfuse/core/slist.c b/lib/webfuse/core/slist.c index fdc1724..5c9dfb1 100644 --- a/lib/webfuse/core/slist.c +++ b/lib/webfuse/core/slist.c @@ -4,14 +4,20 @@ void wf_slist_init( struct wf_slist * list) { - list->first = NULL; - list->last = NULL; + list->head.next = NULL; + list->last = &list->head; } bool wf_slist_empty( struct wf_slist * list) { - return (NULL == list->first); + return (list->last == &list->head); +} + +struct wf_slist_item * wf_slist_first( + struct wf_slist * list) +{ + return list->head.next; } void wf_slist_append( @@ -19,58 +25,36 @@ void wf_slist_append( struct wf_slist_item * item) { item->next = NULL; + list->last->next = item; + list->last = item; - if (NULL != list->last) + if (NULL == list->head.next) { - list->last->next = item; - list->last = item; - } - else - { - list->first = item; - list->last = item; + list->head.next = item; } } struct wf_slist_item * wf_slist_remove_first( struct wf_slist * list) { - struct wf_slist_item * const result = list->first; - if (NULL != result) - { - list->first = list->first->next; - if (NULL == list->first) - { - list->last = NULL; - } - } - - return result; + return wf_slist_remove_after(list, &list->head); } struct wf_slist_item * wf_slist_remove_after( struct wf_slist * list, struct wf_slist_item * prev) { - struct wf_slist_item * result = NULL; - if (NULL != prev) + struct wf_slist_item * result = prev->next; + + if (NULL != result) { - result = prev->next; - if ((NULL != result) && (NULL != result->next)) - { - prev->next = result->next; - } - else + prev->next = result->next; + + if (list->last == result) { list->last = prev; - prev->next = NULL; - } - - } - else - { - result = wf_slist_remove_first(list); + } } return result; diff --git a/lib/webfuse/core/slist.h b/lib/webfuse/core/slist.h index 5073ff3..b5530b5 100644 --- a/lib/webfuse/core/slist.h +++ b/lib/webfuse/core/slist.h @@ -17,7 +17,7 @@ struct wf_slist_item struct wf_slist { - struct wf_slist_item * first; + struct wf_slist_item head; struct wf_slist_item * last; }; @@ -27,6 +27,9 @@ extern void wf_slist_init( extern bool wf_slist_empty( struct wf_slist * list); +extern struct wf_slist_item * wf_slist_first( + struct wf_slist * list); + extern void wf_slist_append( struct wf_slist * list, struct wf_slist_item * item); diff --git a/test/test_slist.cc b/test/test_slist.cc index c6995fa..ddfb57d 100644 --- a/test/test_slist.cc +++ b/test/test_slist.cc @@ -1,35 +1,139 @@ #include #include "webfuse/core/slist.h" -TEST(wf_slist_remove_after, RemoveFirst) +TEST(wf_slist, init) { struct wf_slist list; - struct wf_slist_item item[10]; + wf_slist_init(&list); + + ASSERT_EQ(nullptr, list.head.next); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&list.head, list.last); + ASSERT_TRUE(wf_slist_empty(&list)); + ASSERT_EQ(nullptr, wf_slist_first(&list)); +} + +TEST(wf_slist, append) +{ + struct wf_slist list; + struct wf_slist_item item[3]; wf_slist_init(&list); + ASSERT_TRUE(wf_slist_empty(&list)); + wf_slist_append(&list, &item[0]); + ASSERT_NE(&list.head, list.last); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[0], wf_slist_first(&list)); + ASSERT_EQ(&item[0], list.head.next); + ASSERT_EQ(&item[0], list.last); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(nullptr, item[0].next); - wf_slist_item * removed = wf_slist_remove_after(&list, NULL); - ASSERT_TRUE(wf_slist_empty(&list)); - ASSERT_EQ(nullptr, list.first); - ASSERT_EQ(nullptr, list.last); + wf_slist_append(&list, &item[1]); + ASSERT_NE(&list.head, list.last); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[0], wf_slist_first(&list)); + ASSERT_EQ(&item[0], list.head.next); + ASSERT_EQ(&item[1], list.last); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&item[1], item[0].next); + ASSERT_EQ(nullptr, item[1].next); + + wf_slist_append(&list, &item[2]); + ASSERT_NE(&list.head, list.last); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[0], wf_slist_first(&list)); + ASSERT_EQ(&item[0], list.head.next); + ASSERT_EQ(&item[2], list.last); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&item[1], item[0].next); + ASSERT_EQ(&item[2], item[1].next); + ASSERT_EQ(nullptr, item[2].next); +} + +TEST(wf_slist_remove_after, remove_first) +{ + struct wf_slist list; + struct wf_slist_item item[3]; + + wf_slist_init(&list); + wf_slist_append(&list, &item[0]); + wf_slist_append(&list, &item[1]); + wf_slist_append(&list, &item[2]); + + wf_slist_item * removed; + + removed = wf_slist_remove_first(&list); + ASSERT_FALSE(wf_slist_empty(&list)); ASSERT_EQ(&item[0], removed); + + removed = wf_slist_remove_first(&list); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[1], removed); + + removed = wf_slist_remove_first(&list); + ASSERT_TRUE(wf_slist_empty(&list)); + ASSERT_EQ(&item[2], removed); + + ASSERT_EQ(nullptr, list.head.next); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&list.head, list.last); + ASSERT_EQ(nullptr, wf_slist_first(&list)); } -TEST(wf_slist_remove_after, RemoveLast) +TEST(wf_slist_remove_after, remove_last) { struct wf_slist list; - struct wf_slist_item item[10]; + struct wf_slist_item item[3]; wf_slist_init(&list); wf_slist_append(&list, &item[0]); wf_slist_append(&list, &item[1]); wf_slist_append(&list, &item[2]); - wf_slist_item * removed = wf_slist_remove_after(&list, &item[1]); + wf_slist_item * removed; + + removed = wf_slist_remove_after(&list, &item[1]); ASSERT_FALSE(wf_slist_empty(&list)); - ASSERT_EQ(&item[0], list.first); - ASSERT_EQ(&item[1], list.last); - ASSERT_EQ(nullptr, item[1].next); ASSERT_EQ(&item[2], removed); + + removed = wf_slist_remove_after(&list, &item[0]); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[1], removed); + + removed = wf_slist_remove_after(&list, &list.head); + ASSERT_TRUE(wf_slist_empty(&list)); + ASSERT_EQ(&item[0], removed); + + ASSERT_EQ(nullptr, list.head.next); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&list.head, list.last); + ASSERT_EQ(nullptr, wf_slist_first(&list)); +} + +TEST(wf_slist_remove_after, remove_after) +{ + struct wf_slist list; + struct wf_slist_item item[3]; + + wf_slist_init(&list); + wf_slist_append(&list, &item[0]); + wf_slist_append(&list, &item[1]); + wf_slist_append(&list, &item[2]); + + wf_slist_item * removed; + + removed = wf_slist_remove_after(&list, &item[0]); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[1], removed); + + ASSERT_NE(&list.head, list.last); + ASSERT_FALSE(wf_slist_empty(&list)); + ASSERT_EQ(&item[0], wf_slist_first(&list)); + ASSERT_EQ(&item[0], list.head.next); + ASSERT_EQ(&item[2], list.last); + ASSERT_EQ(nullptr, list.last->next); + ASSERT_EQ(&item[2], item[0].next); + ASSERT_EQ(nullptr, item[2].next); }