X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Fllist.c;h=401a4ba5d92280901c5782e48cda24443842cd98;hb=9ee6c7fc9932e3fcb6d8aebe5364b1da3116af05;hp=3f54786074941d368bc88da4ca475b8cd2559e7c;hpb=982e6a7ccff9493d3faec0d0327634c2a13ac019;p=sysdb.git diff --git a/src/utils/llist.c b/src/utils/llist.c index 3f54786..401a4ba 100644 --- a/src/utils/llist.c +++ b/src/utils/llist.c @@ -117,12 +117,11 @@ sdb_llist_insert_after(sdb_llist_t *list, sdb_llist_elem_t *elem, static sdb_llist_elem_t * llist_search(sdb_llist_t *list, - sdb_llist_lookup_cb lookup, void *user_data) + sdb_llist_lookup_cb lookup, const void *user_data) { sdb_llist_elem_t *elem; - if ((! list) || (! lookup)) - return NULL; + assert(list && lookup); for (elem = list->head; elem; elem = elem->next) if (! lookup(elem->obj, user_data)) @@ -305,12 +304,31 @@ sdb_llist_insert_sorted(sdb_llist_t *list, return status; } /* sdb_llist_insert_sorted */ +sdb_object_t * +sdb_llist_get(sdb_llist_t *list, size_t i) +{ + sdb_llist_elem_t *elem; + size_t j; + + if ((! list) || (i >= list->length)) + return NULL; + + for (elem = list->head, j = 0; j < i; elem = elem->next, ++j) + /* iterate */; + + assert(elem); + return elem->obj; +} /* sdb_llist_get */ + sdb_object_t * sdb_llist_search(sdb_llist_t *list, - sdb_llist_lookup_cb lookup, void *user_data) + sdb_llist_lookup_cb lookup, const void *user_data) { sdb_llist_elem_t *elem; + if ((! list) || (! lookup)) + return NULL; + pthread_rwlock_rdlock(&list->lock); elem = llist_search(list, lookup, user_data); pthread_rwlock_unlock(&list->lock); @@ -343,11 +361,14 @@ sdb_llist_search_by_name(sdb_llist_t *list, const char *key) sdb_object_t * sdb_llist_remove(sdb_llist_t *list, - sdb_llist_lookup_cb lookup, void *user_data) + sdb_llist_lookup_cb lookup, const void *user_data) { sdb_llist_elem_t *elem; sdb_object_t *obj = NULL; + if ((! list) || (! lookup)) + return NULL; + pthread_rwlock_wrlock(&list->lock); elem = llist_search(list, lookup, user_data); if (elem) @@ -422,6 +443,11 @@ sdb_llist_iter_get_next(sdb_llist_iter_t *iter) pthread_rwlock_rdlock(&iter->list->lock); + /* XXX: increment ref-cnt for this object? + * also: when letting an element take ownership of next and prev + * elements, this might be a fairly cheap way to implement a weak + * type of snapshotting */ + obj = iter->elem->obj; iter->elem = iter->elem->next; @@ -429,5 +455,37 @@ sdb_llist_iter_get_next(sdb_llist_iter_t *iter) return obj; } /* sdb_llist_iter_get_next */ +int +sdb_llist_iter_remove_current(sdb_llist_iter_t *iter) +{ + sdb_llist_elem_t *elem; + + if ((! iter) || (! iter->list)) + return -1; + + pthread_rwlock_wrlock(&iter->list->lock); + + if (! iter->elem) /* reached end of list */ + elem = iter->list->tail; + else + elem = iter->elem->prev; + if (elem) + sdb_llist_remove_elem(iter->list, elem); + + pthread_rwlock_unlock(&iter->list->lock); + + if (! elem) + return -1; + return 0; +} /* sdb_llist_iter_remove */ + +size_t +sdb_llist_len(sdb_llist_t *list) +{ + if (! list) + return 0; + return list->length; +} /* sdb_llist_len */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */