mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
added function to remove elements from list
This commit is contained in:
parent
23aec7e83a
commit
232acba2d3
2 changed files with 42 additions and 26 deletions
|
@ -18,8 +18,7 @@
|
|||
|
||||
/** Static list initialization */
|
||||
#define LIST_INIT(dtor) { \
|
||||
.start = NULL, \
|
||||
.end = NULL, \
|
||||
.array = NULL, \
|
||||
.length = 0, \
|
||||
.capacity = 0, \
|
||||
.lock = PTHREAD_MUTEX_INITIALIZER, \
|
||||
|
@ -27,12 +26,12 @@
|
|||
}
|
||||
|
||||
#define list_length(list) ((list)->length)
|
||||
#define list_at(list, index) ((list)->length > index ? (list)->start[index] : NULL)
|
||||
#define list_at(list, index) ((list)->length > index ? (list)->array[index] : NULL)
|
||||
|
||||
#define list_first(list) list_at(list, 0)
|
||||
#define list_last(list) list_at(list, (list)->length-1)
|
||||
#define list_foreach(ptr, list) for (int _i = 0, _p; _p = 1, _i < (list)->length; _i++) \
|
||||
for (ptr = (list)->start[_i]; _p--; )
|
||||
for (ptr = (list)->array[_i]; _p--; )
|
||||
|
||||
/** Callback to destroy list elements.
|
||||
*
|
||||
|
@ -44,10 +43,9 @@ typedef void (*dtor_cb_t)(void *);
|
|||
typedef int (*cmp_cb_t)(const void *, const void *);
|
||||
|
||||
struct list {
|
||||
void **start; /**< Array of pointers to list elements */
|
||||
void **end; /**< Array of pointers to list elements */
|
||||
size_t capacity; /**< Size of list::start in elements */
|
||||
size_t length; /**< Number of elements of list::start which are in use */
|
||||
void **array; /**< Array of pointers to list elements */
|
||||
size_t capacity; /**< Size of list::array in elements */
|
||||
size_t length; /**< Number of elements of list::array which are in use */
|
||||
dtor_cb_t destructor; /**< A destructor which gets called for every list elements during list_destroy() */
|
||||
pthread_mutex_t lock; /**< A mutex to allow thread-safe accesses */
|
||||
};
|
||||
|
@ -61,6 +59,9 @@ void list_destroy(struct list *l);
|
|||
/** Append an element to the end of the list */
|
||||
void list_push(struct list *l, void *p);
|
||||
|
||||
/** Remove all occurences of a list item */
|
||||
void list_remove(struct list *l, void *p);
|
||||
|
||||
/** Search the list for an element whose first element is a character array which matches name.
|
||||
*
|
||||
* @see Only possible because of §1424 of http://c0x.coding-guidelines.com/6.7.2.1.html
|
||||
|
|
51
lib/list.c
51
lib/list.c
|
@ -21,8 +21,7 @@ void list_init(struct list *l, dtor_cb_t dtor)
|
|||
l->length = 0;
|
||||
l->capacity = 0;
|
||||
|
||||
l->start = NULL;
|
||||
l->end = NULL;
|
||||
l->array = NULL;
|
||||
}
|
||||
|
||||
void list_destroy(struct list *l)
|
||||
|
@ -34,10 +33,9 @@ void list_destroy(struct list *l)
|
|||
l->destructor(p);
|
||||
}
|
||||
|
||||
free(l->start);
|
||||
free(l->array);
|
||||
|
||||
l->start =
|
||||
l->end = NULL;
|
||||
l->array = NULL;
|
||||
|
||||
l->length =
|
||||
l->capacity = 0;
|
||||
|
@ -51,36 +49,51 @@ void list_push(struct list *l, void *p)
|
|||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
/* Resize array if out of capacity */
|
||||
if (l->end == l->start + l->capacity) {
|
||||
if (l->length >= l->capacity) {
|
||||
l->capacity += LIST_CHUNKSIZE;
|
||||
l->start = realloc(l->start, l->capacity * sizeof(void *));
|
||||
l->array = realloc(l->array, l->capacity * sizeof(void *));
|
||||
}
|
||||
|
||||
l->start[l->length] = p;
|
||||
l->array[l->length] = p;
|
||||
l->length++;
|
||||
l->end = &l->start[l->length];
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
}
|
||||
|
||||
void * list_lookup(struct list *l, const char *needle)
|
||||
void list_remove(struct list *l, void *p)
|
||||
{
|
||||
int cmp(const void *elm, const void *needle) {
|
||||
char *name = * (char **) elm; /* Ugly hack: the lookup key (name) must be the first element in the list element struct */
|
||||
|
||||
return strcmp(name, needle);
|
||||
int removed = 0;
|
||||
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
for (int i = 0; i < l->length; i++) {
|
||||
if (l->array[i] == p)
|
||||
removed++;
|
||||
else
|
||||
l->array[i - removed] = l->array[i];
|
||||
}
|
||||
|
||||
l->length -= removed;
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
}
|
||||
|
||||
void * list_lookup(struct list *l, const char *name)
|
||||
{
|
||||
int cmp_helper(const void *a, const void *b) {
|
||||
return strcmp(* (char **) a, b);
|
||||
}
|
||||
|
||||
return list_search(l, cmp, (void *) needle);
|
||||
return list_search(l, cmp_helper, (void *) name);
|
||||
}
|
||||
|
||||
int list_contains(struct list *l, void *p)
|
||||
{
|
||||
int cmp(const void *a, const void *b) {
|
||||
int cmp_helper(const void *a, const void *b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
return list_count(l, cmp, p);
|
||||
return list_count(l, cmp_helper, p);
|
||||
}
|
||||
|
||||
int list_count(struct list *l, cmp_cb_t cmp, void *ctx)
|
||||
|
@ -123,6 +136,8 @@ void list_sort(struct list *l, cmp_cb_t cmp)
|
|||
}
|
||||
|
||||
pthread_mutex_lock(&l->lock);
|
||||
qsort(l->start, l->length, sizeof(void *), cmp_helper);
|
||||
|
||||
qsort(l->array, l->length, sizeof(void *), cmp_helper);
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
}
|
Loading…
Add table
Reference in a new issue