added map iterator

Fri, 25 May 2012 17:39:27 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 25 May 2012 17:39:27 +0200
changeset 31
91ac86557290
parent 30
23bb65cbf7a4
child 32
c7af4ec56e19

added map iterator

test/main.c file | annotate | diff | comparison | revisions
test/map_tests.c file | annotate | diff | comparison | revisions
test/map_tests.h file | annotate | diff | comparison | revisions
ucx/dlist.c file | annotate | diff | comparison | revisions
ucx/list.c file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
ucx/string.c file | annotate | diff | comparison | revisions
ucx/string.h file | annotate | diff | comparison | revisions
--- a/test/main.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/test/main.c	Fri May 25 17:39:27 2012 +0200
@@ -111,6 +111,7 @@
         ucx_test_register(suite, test_ucx_key);
         ucx_test_register(suite, test_ucx_map_put);
         ucx_test_register(suite, test_ucx_map_get);
+        ucx_test_register(suite, test_ucx_map_iterator);
         
         ucx_test_run(suite, stdout);
         ucx_test_suite_free(suite);
--- a/test/map_tests.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/test/map_tests.c	Fri May 25 17:39:27 2012 +0200
@@ -71,3 +71,54 @@
 UCX_TEST_BEGIN(test_ucx_map_get) {
     UCX_TEST_END
 }
+
+UCX_TEST_BEGIN(test_ucx_map_iterator) {
+    UcxMap *map = ucx_map_new(16);
+    
+    int v1 = 10;
+    int v2 = 15;
+    int v3 = 7;
+    int v4 = 9;
+    
+    ucx_map_cstr_put(map, "v1", &v1);
+    ucx_map_cstr_put(map, "v2", &v2);
+    ucx_map_cstr_put(map, "v3", &v3);
+    ucx_map_cstr_put(map, "v4", &v4);
+    
+    UcxMapIterator i = ucx_map_iterator(map);
+    int check = 0;
+    int hit = 0;
+    
+    UCX_MAP_FOREACH(int*, v, map, i) {
+        check += *v;
+        hit++;
+    }
+    
+    UCX_TEST_ASSERT(hit == 4, "test1: wrong number of hits");
+    UCX_TEST_ASSERT(check == v1+v2+v3+v4, "test1: wrong result");
+            
+    ucx_map_free(map);
+    
+    map = ucx_map_new(1);
+    ucx_map_cstr_put(map, "v1", &v1);
+    ucx_map_cstr_put(map, "v2", &v2);
+    ucx_map_cstr_put(map, "v3", &v3);
+    ucx_map_cstr_put(map, "v4", &v4);
+    
+    i = ucx_map_iterator(map);
+    check = 0;
+    hit = 0;
+    
+    UCX_MAP_FOREACH(int*, v, map, i) {
+        check += *v;
+        hit++;
+    }
+    
+    UCX_TEST_ASSERT(hit == 4, "test2: wrong number of hits");
+    UCX_TEST_ASSERT(check == v1+v2+v3+v4, "test2: wrong result");
+    
+    
+    ucx_map_free(map);
+    
+    UCX_TEST_END
+}
--- a/test/map_tests.h	Fri Feb 24 15:53:50 2012 +0100
+++ b/test/map_tests.h	Fri May 25 17:39:27 2012 +0200
@@ -16,6 +16,7 @@
 UCX_TEST_DECLARE(test_ucx_key)
 UCX_TEST_DECLARE(test_ucx_map_put)
 UCX_TEST_DECLARE(test_ucx_map_get)
+UCX_TEST_DECLARE(test_ucx_map_iterator)
 
 
 #ifdef	__cplusplus
--- a/ucx/dlist.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/dlist.c	Fri May 25 17:39:27 2012 +0200
@@ -125,8 +125,13 @@
 
 UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e) {
     if (e->prev == NULL) {
-        e->next->prev = NULL;
-        l = e->next;
+        if(e->next != NULL) {
+            e->next->prev = NULL;
+            l = e->next;
+        } else {
+            l = NULL;
+        }
+        
     } else {
         e->prev->next = e->next;
         e->next->prev = e->prev;
--- a/ucx/list.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/list.c	Fri May 25 17:39:27 2012 +0200
@@ -118,7 +118,7 @@
         while (f->next != NULL && f->next != e) {
             f = f->next;
         }
-        /* perform remove iff this element is found in this list */
+        /* perform remove if this element is found in this list */
         if (f->next == e) {
             f->next = e->next;
             free(e);
--- a/ucx/map.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/map.c	Fri May 25 17:39:27 2012 +0200
@@ -148,3 +148,41 @@
 
     return h;
 }
+
+UcxMapIterator ucx_map_iterator(UcxMap *map) {
+    UcxMapIterator i;
+    i.map = map;
+    i.cur = NULL;
+    i.index = 0;
+    return i;
+}
+
+int ucx_map_iter_next(UcxMapIterator *i, void **elm) {
+    UcxMapElement *e = i->cur;
+    
+    if(e == NULL) {
+        e = i->map->map[0];
+    } else {
+        e = e->next;
+    }
+    
+    while(i->index < i->map->size) {
+        if(e != NULL) {
+            if(e->data != NULL) {
+                i->cur = e;
+                *elm = e->data;
+                return 0;
+            }
+
+            e = e->next;
+        } else {
+            i->index++;
+            
+            if(i->index < i->map->size) {
+                e = i->map->map[i->index];
+            }
+        }
+    }
+    
+    return 1;
+}
--- a/ucx/map.h	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/map.h	Fri May 25 17:39:27 2012 +0200
@@ -12,9 +12,13 @@
 extern "C" {
 #endif
 
-typedef struct UcxMap        UcxMap;
-typedef struct UcxKey        UcxKey;
-typedef struct UcxMapElement UcxMapElement;
+#define UCX_MAP_FOREACH(type,elm,map,iter) \
+        for(type elm;ucx_map_iter_next(&iter,(void*)&elm)==0;)
+
+typedef struct UcxMap          UcxMap;
+typedef struct UcxKey          UcxKey;
+typedef struct UcxMapElement   UcxMapElement;
+typedef struct UcxMapIterator  UcxMapIterator;
 
 struct UcxMap {
     UcxMapElement **map;
@@ -33,6 +37,12 @@
     UcxKey        key;
 };
 
+struct UcxMapIterator {
+    UcxMap        *map;
+    UcxMapElement *cur;
+    int           index;
+};
+
 
 UcxMap *ucx_map_new(size_t size);
 void ucx_map_free(UcxMap *map);
@@ -49,6 +59,10 @@
 
 int ucx_hash(char *data, size_t len);
 
+UcxMapIterator ucx_map_iterator(UcxMap *map);
+
+int ucx_map_iter_next(UcxMapIterator *i, void **elm);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/ucx/string.c	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/string.c	Fri May 25 17:39:27 2012 +0200
@@ -90,7 +90,7 @@
     return strncmp(s1.ptr, s2.ptr, s1.length>s2.length ? s2.length: s1.length);
 }
 
-sstr_t sstrdub(sstr_t s) {
+sstr_t sstrdup(sstr_t s) {
     sstr_t newstring;
     newstring.ptr = (char*) malloc(s.length + 1);
     if (newstring.ptr != NULL) {
--- a/ucx/string.h	Fri Feb 24 15:53:50 2012 +0100
+++ b/ucx/string.h	Fri May 25 17:39:27 2012 +0200
@@ -69,7 +69,7 @@
 
 int sstrcmp(sstr_t s1, sstr_t s2);
 
-sstr_t sstrdub(sstr_t s);
+sstr_t sstrdup(sstr_t s);
 
 #ifdef	__cplusplus
 }

mercurial