map uses an allocator

Thu, 11 Jul 2013 17:32:48 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 11 Jul 2013 17:32:48 +0200
changeset 107
86b19c98b5fd
parent 106
a54115d554f7
child 108
d2b1e67b2b48

map uses an allocator

g++-debug.mk file | annotate | diff | comparison | revisions
gcc-debug.mk file | annotate | diff | comparison | revisions
ucx/allocator.c file | annotate | diff | comparison | revisions
ucx/allocator.h file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
--- a/g++-debug.mk	Fri Jun 21 11:18:24 2013 +0200
+++ b/g++-debug.mk	Thu Jul 11 17:32:48 2013 +0200
@@ -31,7 +31,7 @@
 AR = ar
 RM = rm
 
-CFLAGS  = -std=gnu++0x -g -O2 -fstrict-aliasing -Werror -Wall -pedantic -c
+CFLAGS  = -std=gnu++0x -g -O2 -fstrict-aliasing -Wall -pedantic -c
 COFLAGS = -o
 LDFLAGS = 
 LOFLAGS = -o
--- a/gcc-debug.mk	Fri Jun 21 11:18:24 2013 +0200
+++ b/gcc-debug.mk	Thu Jul 11 17:32:48 2013 +0200
@@ -31,7 +31,7 @@
 AR = ar
 RM = rm
 
-CFLAGS  = -std=gnu99 -g -O2 -fstrict-aliasing -Werror -Wall -pedantic -c
+CFLAGS  = -std=gnu99 -g -O2 -fstrict-aliasing -Wall -pedantic -c
 COFLAGS = -o
 LDFLAGS = 
 LOFLAGS = -o
--- a/ucx/allocator.c	Fri Jun 21 11:18:24 2013 +0200
+++ b/ucx/allocator.c	Thu Jul 11 17:32:48 2013 +0200
@@ -29,6 +29,19 @@
 #include <stdlib.h>
 #include "allocator.h"
 
+UcxAllocator default_allocator = {
+    NULL,
+    ucx_default_malloc,
+    ucx_default_calloc,
+    ucx_default_realloc,
+    ucx_default_free
+};
+
+UcxAllocator *ucx_default_allocator() {
+    UcxAllocator *allocator = &default_allocator;
+    return allocator;
+}
+
 void *ucx_default_malloc(void *ignore, size_t n) {
     return malloc(n);
 }
@@ -40,3 +53,7 @@
 void *ucx_default_realloc(void *ignore, void *data, size_t n) {
     return realloc(data, n);
 }
+
+void ucx_default_free(void *ignore, void *data) {
+    free(data);
+}
--- a/ucx/allocator.h	Fri Jun 21 11:18:24 2013 +0200
+++ b/ucx/allocator.h	Thu Jul 11 17:32:48 2013 +0200
@@ -38,20 +38,26 @@
 typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
 typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
 typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
+typedef void(*ucx_allocator_free)(void *pool, void *data);
 
 typedef struct {
     void *pool;
-    ucx_allocator_malloc malloc;
-    ucx_allocator_calloc calloc;
+    ucx_allocator_malloc  malloc;
+    ucx_allocator_calloc  calloc;
     ucx_allocator_realloc realloc;
+    ucx_allocator_free    free;
 } UcxAllocator;
 
+UcxAllocator *ucx_default_allocator();
+
 void *ucx_default_malloc(void *ignore, size_t n);
 void *ucx_default_calloc(void *ignore, size_t n, size_t size);
 void *ucx_default_realloc(void *ignore, void *data, size_t n);
+void ucx_default_free(void *ignore, void *data);
 
 #define UCX_ALLOCATOR_DEFAULT {NULL, \
-        ucx_default_malloc, ucx_default_calloc, ucx_default_realloc}
+        ucx_default_malloc, ucx_default_calloc, ucx_default_realloc, \
+        ucx_default_free }
 
 #ifdef	__cplusplus
 }
--- a/ucx/map.c	Fri Jun 21 11:18:24 2013 +0200
+++ b/ucx/map.c	Thu Jul 11 17:32:48 2013 +0200
@@ -32,18 +32,30 @@
 #include "map.h"
 
 UcxMap *ucx_map_new(size_t size) {
+    return ucx_map_new_allocator(size, NULL);
+}
+
+UcxMap *ucx_map_new_allocator(size_t size, UcxAllocator *allocator) {
     if(size == 0) {
         size = 16;
     }
     
-    UcxMap *map = (UcxMap*)malloc(sizeof(UcxMap));
+    if(!allocator) {
+        allocator = ucx_default_allocator();
+    }
+    
+    UcxMap *map = (UcxMap*)allocator->malloc(allocator->pool, sizeof(UcxMap));
     if(map == NULL) {
         return NULL;
     }
-
-    map->map = (UcxMapElement**)calloc(size, sizeof(UcxMapElement*));
+    
+    map->allocator = allocator;
+    map->map = (UcxMapElement**)allocator->calloc(
+            allocator->pool,
+            size,
+            sizeof(UcxMapElement*));
     if(map->map == NULL) {
-        free(map);
+        allocator->free(allocator->pool, map);
         return NULL;
     }
     map->size = size;
@@ -58,18 +70,18 @@
         if (elem != NULL) {
             do {
                 UcxMapElement *next = elem->next;
-                free(elem->key.data);
+                map->allocator->free(map->allocator->pool, elem->key.data);
                 free(elem);
                 elem = next;
             } while (elem != NULL);
         }
     }
-    free(map->map);
+    map->allocator->free(map->allocator->pool, map->map);
 }
 
 void ucx_map_free(UcxMap *map) {
     ucx_map_free_elmlist(map);
-    free(map);
+    map->allocator->free(map->allocator->pool, map);
 }
 
 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,
@@ -102,9 +114,13 @@
         oldmap.map = map->map;
         oldmap.size = map->size;
         oldmap.count = map->count;
+        oldmap.allocator = map->allocator;
         
         map->size = (map->count * 5) >> 1;
-        map->map = (UcxMapElement**)calloc(map->size, sizeof(UcxMapElement*));
+        map->map = (UcxMapElement**)map->allocator->calloc(
+                map->allocator->pool,
+                map->size,
+                sizeof(UcxMapElement*));
         if(map->map == NULL) {
             *map = oldmap;
             return 1;
@@ -119,6 +135,8 @@
 }
 
 int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
+    UcxAllocator *allocator = map->allocator;
+    
     if(key.hash == 0) {
         key.hash = ucx_hash((char*)key.data, key.len);
     }
@@ -133,7 +151,9 @@
     }
     
     if (elm == NULL || elm->key.hash != key.hash) {
-        UcxMapElement *e = (UcxMapElement*)malloc(sizeof(UcxMapElement));
+        UcxMapElement *e = (UcxMapElement*)allocator->malloc(
+                allocator->pool,
+                sizeof(UcxMapElement));
         if(e == NULL) {
             return -1;
         }
@@ -148,7 +168,7 @@
     }
     
     if(elm->key.data == NULL) {
-        void *kd = malloc(key.len);
+        void *kd = allocator->malloc(allocator->pool, key.len);
         if (kd == NULL) {
             return -1;
         }
@@ -181,7 +201,7 @@
                     } else {
                         map->map[slot] = elm->next;
                     }
-                    free(elm);
+                    map->allocator->free(map->allocator->pool, elm);
                     map->count--;
                 }
 
--- a/ucx/map.h	Fri Jun 21 11:18:24 2013 +0200
+++ b/ucx/map.h	Thu Jul 11 17:32:48 2013 +0200
@@ -55,6 +55,7 @@
 typedef void*(*ucx_map_coder)(void*,void*,size_t*);
 
 struct UcxMap {
+    UcxAllocator  *allocator;
     UcxMapElement **map;
     size_t        size;
     size_t        count;
@@ -80,6 +81,7 @@
 
 
 UcxMap *ucx_map_new(size_t size);
+UcxMap *ucx_map_new_allocator(size_t size, UcxAllocator *allocator);
 void ucx_map_free(UcxMap *map);
 /* you cannot clone maps with more than 390 mio entries */
 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,

mercurial