From f45897e45c57db80b21e31d44723733a17bfac54 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 27 Mar 2021 22:05:07 +0100 Subject: lib: typesafe *_member() This provides a "is this item on this list" check, which may or may not be faster than using *_find() for the same purpose. (If the container has no faster way of doing it, it falls back to using *_find().) Signed-off-by: David Lamparter --- lib/typesafe.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'lib/typesafe.c') diff --git a/lib/typesafe.c b/lib/typesafe.c index 76705fad0d..f886c5bdf6 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -29,6 +29,44 @@ DEFINE_MTYPE_STATIC(LIB, TYPEDHASH_BUCKET, "Typed-hash bucket"); DEFINE_MTYPE_STATIC(LIB, SKIPLIST_OFLOW, "Skiplist overflow"); DEFINE_MTYPE_STATIC(LIB, HEAP_ARRAY, "Typed-heap array"); +bool typesafe_list_member(const struct slist_head *head, + const struct slist_item *item) +{ + struct slist_item *fromhead = head->first; + struct slist_item **fromnext = (struct slist_item **)&item->next; + + while (fromhead) { + if (fromhead == item || fromnext == head->last_next) + return true; + + fromhead = fromhead->next; + if (!*fromnext) + break; + fromnext = &(*fromnext)->next; + } + + return false; +} + +bool typesafe_dlist_member(const struct dlist_head *head, + const struct dlist_item *item) +{ + const struct dlist_item *fromhead = head->hitem.next; + const struct dlist_item *fromitem = item->next; + + if (!item->prev || !item->next) + return false; + + while (fromhead != &head->hitem && fromitem != item) { + if (fromitem == &head->hitem || fromhead == item) + return true; + fromhead = fromhead->next; + fromitem = fromitem->next; + } + + return false; +} + #if 0 static void hash_consistency_check(struct thash_head *head) { -- cgit v1.2.3