From 6b0447f565efd31c0e803806d710a5d443490b65 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 24 Feb 2019 09:22:20 +0100 Subject: [PATCH] list: add vlist_{insert, remove, remove_all}() and corresponding tests --- common/include/villas/list.h | 7 ++++- common/lib/list.c | 54 +++++++++++++++++++++++++++++++++++- common/tests/unit/list.cpp | 19 ++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/common/include/villas/list.h b/common/include/villas/list.h index 09e4f1aa4..295d00fa2 100644 --- a/common/include/villas/list.h +++ b/common/include/villas/list.h @@ -87,7 +87,11 @@ int vlist_destroy(struct vlist *l, dtor_cb_t dtor, bool free); void vlist_push(struct vlist *l, void *p); /** Remove all occurences of a list item */ -void vlist_remove(struct vlist *l, void *p); +void vlist_remove_all(struct vlist *l, void *p); + +int vlist_remove(struct vlist *l, size_t idx); + +int vlist_insert(struct vlist *l, size_t idx, void *p); /** Return the first list element which is identified by a string in its first member variable. * @@ -132,6 +136,7 @@ void vlist_extend(struct vlist *l, size_t len, void *val); /** Shallow copy a list. */ int vlist_copy(struct vlist *dst, const struct vlist *src); + #ifdef __cplusplus } #endif diff --git a/common/lib/list.c b/common/lib/list.c index 533ed5e14..4b4418060 100644 --- a/common/lib/list.c +++ b/common/lib/list.c @@ -111,7 +111,59 @@ void vlist_push(struct vlist *l, void *p) pthread_mutex_unlock(&l->lock); } -void vlist_remove(struct vlist *l, void *p) +int vlist_remove(struct vlist *l, size_t idx) +{ + pthread_mutex_lock(&l->lock); + + assert(l->state == STATE_INITIALIZED); + + if (idx >= l->length) + return -1; + + for (size_t i = idx; i < l->length - 1; i++) + l->array[i] = l->array[i+1]; + + l->length--; + + pthread_mutex_unlock(&l->lock); + + return 0; +} + +int vlist_insert(struct vlist *l, size_t idx, void *p) +{ + size_t i; + void *t, *o; + + pthread_mutex_lock(&l->lock); + + assert(l->state == STATE_INITIALIZED); + + if (idx >= l->length) + return -1; + + /* Resize array if out of capacity */ + if (l->length + 1 > l->capacity) { + l->capacity += LIST_CHUNKSIZE; + l->array = realloc(l->array, l->capacity * sizeof(void *)); + } + + o = p; + for (i = idx; i < l->length; i++) { + t = l->array[i]; + l->array[i] = o; + o = t; + } + + l->array[l->length] = o; + l->length++; + + pthread_mutex_unlock(&l->lock); + + return 0; +} + +void vlist_remove_all(struct vlist *l, void *p) { int removed = 0; diff --git a/common/tests/unit/list.cpp b/common/tests/unit/list.cpp index 8bf2a5f7e..16dbb24a0 100644 --- a/common/tests/unit/list.cpp +++ b/common/tests/unit/list.cpp @@ -155,7 +155,24 @@ Test(list, basics) ret = vlist_contains(&l, (void *) 55); cr_assert(ret); - vlist_remove(&l, (void *) 55); + void *before_ptr = vlist_at(&l, 12); + + ret = vlist_insert(&l, 12, (void *) 123); + cr_assert_eq(ret, 0); + cr_assert_eq(vlist_at(&l, 12), (void *) 123, "Is: %p", vlist_at(&l, 12)); + + ret = vlist_remove(&l, 12); + cr_assert_eq(ret, 0); + cr_assert_eq(vlist_at(&l, 12), before_ptr); + + int counts, before_len; + + before_len = vlist_length(&l); + counts = vlist_contains(&l, (void *) 55); + cr_assert_gt(counts, 0); + + vlist_remove_all(&l, (void *) 55); + cr_assert_eq(vlist_length(&l), before_len - counts); ret = vlist_contains(&l, (void *) 55); cr_assert(!ret);