From 9a496f231cdaeb77da9b6f0ac8f77bac20fbd19c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 3 Oct 2009 18:23:39 +0000 Subject: fixing slist api and implementation --- src/include/gnunet_container_lib.h | 35 ++++++++++--- src/transport/transport_api.c | 3 ++ src/util/container_slist.c | 105 +++++++++++++++++++++---------------- src/util/test_container_slist.c | 8 ++- 4 files changed, 93 insertions(+), 58 deletions(-) diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h index 8abf10e21..b63ced75b 100644 --- a/src/include/gnunet_container_lib.h +++ b/src/include/gnunet_container_lib.h @@ -876,10 +876,14 @@ GNUNET_CONTAINER_heap_get_size (struct GNUNET_CONTAINER_Heap *heap); /* ******************** Singly linked list *************** */ -/* Handle to a singly linked list */ +/** + * Handle to a singly linked list + */ struct GNUNET_CONTAINER_SList; -/* Handle to a singly linked list iterator */ +/** + * Handle to a singly linked list iterator + */ struct GNUNET_CONTAINER_SList_Iterator; @@ -892,11 +896,13 @@ struct GNUNET_CONTAINER_SList_Iterator; */ void GNUNET_CONTAINER_slist_add (struct GNUNET_CONTAINER_SList *l, int disp, const void *buf, size_t len); + /** * Create a new singly linked list * @return the new list */ -struct GNUNET_CONTAINER_SList *GNUNET_CONTAINER_slist_create (); +struct GNUNET_CONTAINER_SList *GNUNET_CONTAINER_slist_create (void); + /** * Destroy a singly linked list @@ -904,19 +910,25 @@ struct GNUNET_CONTAINER_SList *GNUNET_CONTAINER_slist_create (); */ void GNUNET_CONTAINER_slist_destroy (struct GNUNET_CONTAINER_SList *l); + /** * Return the beginning of a list + * * @param l list - * @return iterator pointing to the beginning + * @return iterator pointing to the beginning, free using "GNUNET_free" */ -const struct GNUNET_CONTAINER_SList_Iterator *GNUNET_CONTAINER_slist_begin(const struct GNUNET_CONTAINER_SList *l); +struct GNUNET_CONTAINER_SList_Iterator * +GNUNET_CONTAINER_slist_begin(struct GNUNET_CONTAINER_SList *l); + /** * Clear a list + * * @param l list */ void GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l); + /** * Check if a list contains a certain element * @param l list @@ -925,6 +937,7 @@ void GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l); */ int GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, const void *buf, size_t len); + /** * Count the elements of a list * @param l list @@ -932,12 +945,14 @@ int GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, con */ int GNUNET_CONTAINER_slist_count (const struct GNUNET_CONTAINER_SList *l); + /** * Remove an element from the list * @param i iterator that points to the element to be removed */ void GNUNET_CONTAINER_slist_erase (struct GNUNET_CONTAINER_SList_Iterator *i); + /** * Insert an element into a list at a specific position * @param before where to insert the new element @@ -947,6 +962,7 @@ void GNUNET_CONTAINER_slist_erase (struct GNUNET_CONTAINER_SList_Iterator *i); */ void GNUNET_CONTAINER_slist_insert (struct GNUNET_CONTAINER_SList_Iterator *before, int disp, const void *buf, size_t len); + /** * Advance an iterator to the next element * @param i iterator @@ -954,6 +970,7 @@ void GNUNET_CONTAINER_slist_insert (struct GNUNET_CONTAINER_SList_Iterator *befo */ int GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i); + /** * Check if an iterator points beyond the end of a list * @param i iterator @@ -962,13 +979,17 @@ int GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i); */ int GNUNET_CONTAINER_slist_end (struct GNUNET_CONTAINER_SList_Iterator *i); + /** * Retrieve the element at a specific position in a list + * * @param i iterator - * @param len payload length + * @param len set to the payload length * @return payload */ -void *GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i, size_t *len); +const void * +GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i, + size_t *len); #if 0 /* keep Emacsens' auto-indent happy */ diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index c71b15549..8d08f82d9 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -1150,6 +1150,9 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TRANSPORT_TransmitHandle *pos; struct NeighbourList *n; + fprintf (stderr, + "Trying to reconnect to transport!\n"); + /* Forget about all neighbours that we used to be connected to */ while (NULL != (n = h->neighbours)) diff --git a/src/util/container_slist.c b/src/util/container_slist.c index c279bb2ea..874068bdb 100644 --- a/src/util/container_slist.c +++ b/src/util/container_slist.c @@ -29,19 +29,21 @@ struct GNUNET_CONTAINER_SList_Elem { - void *elem; + struct GNUNET_CONTAINER_SList_Elem *next; + const void *elem; size_t len; int disp; - struct GNUNET_CONTAINER_SList_Elem *next; }; struct GNUNET_CONTAINER_SList { - struct GNUNET_CONTAINER_SList_Elem head; + struct GNUNET_CONTAINER_SList_Elem *head; + unsigned int length; }; struct GNUNET_CONTAINER_SList_Iterator { + struct GNUNET_CONTAINER_SList *list; struct GNUNET_CONTAINER_SList_Elem *last; struct GNUNET_CONTAINER_SList_Elem *elem; }; @@ -59,20 +61,23 @@ create_elem (int disp, const void *buf, size_t len) { struct GNUNET_CONTAINER_SList_Elem *e; - e = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList_Elem)); - e->disp = disp; if (disp == GNUNET_MEM_DISP_TRANSIENT) { - e->elem = GNUNET_malloc (len); - memcpy (e->elem, buf, len); + e = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList_Elem) + len); + memcpy (&e[1], buf, len); + e->elem = (const void*) &e[1]; } else - e->elem = (void *) buf; + { + e = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList_Elem)); + e->elem = buf; + } + e->disp = disp; e->len = len; - return e; } + /** * Add a new element to the list * @param l list @@ -87,10 +92,12 @@ GNUNET_CONTAINER_slist_add (struct GNUNET_CONTAINER_SList *l, int disp, struct GNUNET_CONTAINER_SList_Elem *e; e = create_elem (disp, buf, len); - e->next = l->head.next; - l->head.next = e; + e->next = l->head; + l->head = e; + l->length++; } + /** * Create a new singly linked list * @return the new list @@ -98,15 +105,7 @@ GNUNET_CONTAINER_slist_add (struct GNUNET_CONTAINER_SList *l, int disp, struct GNUNET_CONTAINER_SList * GNUNET_CONTAINER_slist_create () { - struct GNUNET_CONTAINER_SList *ret; - - ret = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList)); - if (NULL == ret) - return NULL; - - memset (&ret->head, 0, sizeof (struct GNUNET_CONTAINER_SList)); - - return ret; + return GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList)); } /** @@ -120,22 +119,24 @@ GNUNET_CONTAINER_slist_destroy (struct GNUNET_CONTAINER_SList *l) GNUNET_free (l); } + /** * Return the beginning of a list * @param l list * @return iterator pointing to the beginning */ -const struct GNUNET_CONTAINER_SList_Iterator * -GNUNET_CONTAINER_slist_begin (const struct GNUNET_CONTAINER_SList *l) +struct GNUNET_CONTAINER_SList_Iterator * +GNUNET_CONTAINER_slist_begin (struct GNUNET_CONTAINER_SList *l) { struct GNUNET_CONTAINER_SList_Iterator *ret; ret = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_SList_Iterator)); - ret->elem = l->head.next; - ret->last = (struct GNUNET_CONTAINER_SList_Elem *) &l->head; + ret->elem = l->head; + ret->list = l; return ret; } + /** * Clear a list * @param l list @@ -143,22 +144,24 @@ GNUNET_CONTAINER_slist_begin (const struct GNUNET_CONTAINER_SList *l) void GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l) { - struct GNUNET_CONTAINER_SList_Elem *e, *n; + struct GNUNET_CONTAINER_SList_Elem *e; + struct GNUNET_CONTAINER_SList_Elem *n; - e = l->head.next; + e = l->head; while (e != NULL) { - if (e->disp != GNUNET_MEM_DISP_STATIC) - GNUNET_free (e->elem); n = e->next; GNUNET_free (e); e = n; } - l->head.next = NULL; + l->head = NULL; + l->length = 0; } + /** * Check if a list contains a certain element + * * @param l list * @param buf payload buffer to find * @param lenght of the payload @@ -169,13 +172,14 @@ GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, { struct GNUNET_CONTAINER_SList_Elem *e; - for (e = l->head.next; e != NULL; e = e->next) - if (e->len == len && memcmp (buf, e->elem, len) == 0) + for (e = l->head; e != NULL; e = e->next) + if ( (e->len == len) && + (memcmp (buf, e->elem, len) == 0) ) return GNUNET_YES; - return GNUNET_NO; } + /** * Count the elements of a list * @param l list @@ -184,17 +188,13 @@ GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l, int GNUNET_CONTAINER_slist_count (const struct GNUNET_CONTAINER_SList *l) { - int n; - struct GNUNET_CONTAINER_SList_Elem *e; - - for (n = 0, e = l->head.next; e != NULL; e = e->next) - n++; - - return n; + return l->length; } + /** * Remove an element from the list + * * @param i iterator that points to the element to be removed */ void @@ -203,13 +203,16 @@ GNUNET_CONTAINER_slist_erase (struct GNUNET_CONTAINER_SList_Iterator *i) struct GNUNET_CONTAINER_SList_Elem *next; next = i->elem->next; - i->last->next = next; - if (i->elem->disp != GNUNET_MEM_DISP_STATIC) - GNUNET_free (i->elem->elem); + if (i->last != NULL) + i->last->next = next; + else + i->list->head = next; GNUNET_free (i->elem); + i->list->length--; i->elem = next; } + /** * Insert an element into a list at a specific position * @param before where to insert the new element @@ -225,9 +228,14 @@ GNUNET_CONTAINER_slist_insert (struct GNUNET_CONTAINER_SList_Iterator *before, e = create_elem (disp, buf, len); e->next = before->elem; - before->last->next = e; + if (before->last != NULL) + before->last->next = e; + else + before->list->head = e; + before->list->length++; } + /** * Advance an iterator to the next element * @param i iterator @@ -239,11 +247,13 @@ GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i) i->last = i->elem; i->elem = i->elem->next; - return i->elem != NULL; + return (i->elem != NULL) ? GNUNET_YES : GNUNET_NO; } + /** * Check if an iterator points beyond the end of a list + * * @param i iterator * @return GNUNET_YES if the end has been reached, GNUNET_NO if the iterator * points to a valid element @@ -251,16 +261,17 @@ GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i) int GNUNET_CONTAINER_slist_end (struct GNUNET_CONTAINER_SList_Iterator *i) { - return i->elem == NULL; + return (i->elem == NULL) ? GNUNET_YES : GNUNET_NO; } + /** * Retrieve the element at a specific position in a list * @param i iterator * @param len payload length * @return payload */ -void * +const void * GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i, size_t * len) { @@ -268,3 +279,5 @@ GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i, *len = i->elem->len; return i->elem->elem; } + +/* end of container_slist.c */ diff --git a/src/util/test_container_slist.c b/src/util/test_container_slist.c index a22d4be8a..9d75f1695 100644 --- a/src/util/test_container_slist.c +++ b/src/util/test_container_slist.c @@ -37,7 +37,7 @@ main (int argc, char *argv[]) struct GNUNET_CONTAINER_SList *l; struct GNUNET_CONTAINER_SList_Iterator *it; unsigned int i, j, s; - + const void *p; GNUNET_log_setup ("test-container-slist", "WARNING", NULL); @@ -53,8 +53,6 @@ main (int argc, char *argv[]) GNUNET_CONTAINER_slist_end (it) != GNUNET_YES; GNUNET_CONTAINER_slist_next (it), i--) { - void *p; - p = GNUNET_CONTAINER_slist_get (it, &s); CHECK (p != NULL); j = *(int *) p; @@ -65,6 +63,7 @@ main (int argc, char *argv[]) GNUNET_CONTAINER_slist_insert (it, GNUNET_MEM_DISP_TRANSIENT, &j, sizeof (j)); } + GNUNET_free (it); CHECK (GNUNET_CONTAINER_slist_count (l) == 200); i = 198; CHECK (GNUNET_CONTAINER_slist_contains (l, &i, sizeof (i))); @@ -72,8 +71,6 @@ main (int argc, char *argv[]) for (it = GNUNET_CONTAINER_slist_begin (l); GNUNET_CONTAINER_slist_end (it) != GNUNET_YES;) { - void *p; - p = GNUNET_CONTAINER_slist_get (it, &s); CHECK (p != NULL); CHECK (s == sizeof (i)); @@ -91,6 +88,7 @@ main (int argc, char *argv[]) GNUNET_CONTAINER_slist_erase (it); } + GNUNET_free (it); CHECK (GNUNET_CONTAINER_slist_count (l) == 100); i = 99; CHECK (GNUNET_CONTAINER_slist_contains (l, &i, sizeof (i)) == GNUNET_NO); -- cgit v1.2.3