ucx/map.c

Fri, 30 Nov 2012 21:18:13 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 30 Nov 2012 21:18:13 +0100
changeset 1
1bcaac272cdf
child 5
88625853ae74
permissions
-rw-r--r--

added existing source code

1
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 *
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 #include <stdlib.h>
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 #include <string.h>
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 #include "map.h"
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 UcxMap *ucx_map_new(size_t size) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 if(size == 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 size = 16;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 UcxMap *map = (UcxMap*)malloc(sizeof(UcxMap));
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 if(map == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 return NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 map->map = (UcxMapElement**)calloc(size, sizeof(UcxMapElement*));
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 if(map->map == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 free(map);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 return NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 map->size = size;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 map->count = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28 return map;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 void ucx_map_free_elmlist(UcxMap *map) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 for (size_t n = 0 ; n < map->size ; n++) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 UcxMapElement *elem = map->map[n];
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 if (elem != NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35 do {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 UcxMapElement *next = elem->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 free(elem->key.data);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 free(elem);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 elem = next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 } while (elem != NULL);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 free(map->map);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 void ucx_map_free(UcxMap *map) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 ucx_map_free_elmlist(map);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 free(map);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 copy_func fnc, void *data) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 UcxMapIterator i = ucx_map_iterator(from);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 void *value;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 UCX_MAP_FOREACH(value, i) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 if(ret != 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 size_t bs = (map->count * 5) >> 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 if(newmap == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 return NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 ucx_map_copy(map, newmap, fnc, data);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 return newmap;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 int ucx_map_rehash(UcxMap *map) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 size_t load = (map->size * 3) >> 2;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 if (map->count > load) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 UcxMap oldmap;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 oldmap.map = map->map;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 oldmap.size = map->size;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 oldmap.count = map->count;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 map->size = (map->count * 5) >> 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 map->map = (UcxMapElement**)calloc(map->size, sizeof(UcxMapElement*));
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 if(map->map == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 *map = oldmap;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 map->count = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 ucx_map_copy(&oldmap, map, NULL, NULL);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 /* free the UcxMapElement list of oldmap */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 ucx_map_free_elmlist(&oldmap);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 if(key.hash == 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 key.hash = ucx_hash((char*)key.data, key.len);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 size_t slot = key.hash%map->size;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 UcxMapElement *restrict elm = map->map[slot];
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 UcxMapElement *restrict prev = NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 while (elm != NULL && elm->key.hash < key.hash) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 prev = elm;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 elm = elm->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 if (elm == NULL || elm->key.hash != key.hash) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 UcxMapElement *e = (UcxMapElement*)malloc(sizeof(UcxMapElement));
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 if(e == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 return -1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 e->key.data = NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 if (prev) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 prev->next = e;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 map->map[slot] = e;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 e->next = elm;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 elm = e;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 if(elm->key.data == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 void *kd = malloc(key.len);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 if (kd == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 return -1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 memcpy(kd, key.data, key.len);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 key.data = kd;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 elm->key = key;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 map->count++;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 elm->data = data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, _Bool remove) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 if(key.hash == 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 key.hash = ucx_hash((char*)key.data, key.len);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 size_t slot = key.hash%map->size;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 UcxMapElement *restrict elm = map->map[slot];
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 UcxMapElement *restrict pelm = NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 while (elm && elm->key.hash <= key.hash) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 if(elm->key.hash == key.hash) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 int n = (key.len > elm->key.len) ? elm->key.len : key.len;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 if (memcmp(elm->key.data, key.data, n) == 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 void *data = elm->data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 if (remove) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 if (pelm) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 pelm->next = elm->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 map->map[slot] = elm->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 free(elm);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 map->count--;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 return data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 pelm = elm;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 elm = pelm->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 return NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 void *ucx_map_get(UcxMap *map, UcxKey key) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 return ucx_map_get_and_remove(map, key, 0);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 void *ucx_map_remove(UcxMap *map, UcxKey key) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 return ucx_map_get_and_remove(map, key, 1);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 UcxKey ucx_key(void *data, size_t len) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 UcxKey key;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 key.data = data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 key.len = len;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 key.hash = ucx_hash((const char*) data, len);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 return key;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 int ucx_hash(const char *data, size_t len) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 /* murmur hash 2 */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 int m = 0x5bd1e995;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 int r = 24;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 int h = 25 ^ len;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 int i = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 while (len >= 4) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 int k = data[i + 0] & 0xFF;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 k |= (data[i + 1] & 0xFF) << 8;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 k |= (data[i + 2] & 0xFF) << 16;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 k |= (data[i + 3] & 0xFF) << 24;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 k *= m;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 k ^= k >> r;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 k *= m;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 h *= m;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 h ^= k;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 i += 4;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 len -= 4;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 switch (len) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 case 3: h ^= (data[i + 2] & 0xFF) << 16;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 /* no break */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 case 2: h ^= (data[i + 1] & 0xFF) << 8;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 /* no break */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 case 1: h ^= (data[i + 0] & 0xFF); h *= m;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 /* no break */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 h ^= h >> 13;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 h *= m;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 h ^= h >> 15;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 return h;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 UcxMapIterator ucx_map_iterator(UcxMap *map) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 UcxMapIterator i;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 i.map = map;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 i.cur = NULL;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 i.index = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 return i;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 int ucx_map_iter_next(UcxMapIterator *i, void **elm) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 UcxMapElement *e = i->cur;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 if(e == NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 e = i->map->map[0];
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 e = e->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 while(i->index < i->map->size) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 if(e != NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 if(e->data != NULL) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 i->cur = e;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 *elm = e->data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 e = e->next;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 i->index++;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 if(i->index < i->map->size) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 e = i->map->map[i->index];
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
266 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 int ucx_map_load_enc(UcxMap *map, FILE *f, UcxAllocator allocator,
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272 ucx_map_coder decoder, void* decdata) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 int c; int r, n;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 char *key, *value;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 while ((c = fgetc(f)) > 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 /* Discard leading spaces and comments */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 if (c < 33) continue;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 if (c == '#' || c == '!') {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 while ((c = (char) fgetc(f)) > 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 if (c == '\n') break;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285 continue;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 /* read into key buffer */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 n = 16;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 key = (char*) malloc(n);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 r = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 do {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 if (c == '=') break;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 if (r > n - 2) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 n *= 2;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 key = (char*) realloc(key, n);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 key[r] = c;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 r++;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 } while ((c = fgetc(f)) > 0);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 if (c <= 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 free(key);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 key[r] = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 while (key[--r] == ' ') key[r] = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 /* skip whitespaces */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 while ((c = fgetc(f)) > 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 if (c > 32) break;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 if (c <= 0) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 free(key);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 /* read into value buffer */
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 n = 64;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 value = (char*) malloc(n);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 r = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 do {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322 if (c == '\n') break;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 if (r > n - 2) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 n *= 2;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 value = (char*) realloc(value, n);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 value[r] = c;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328 r++;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 } while ((c = fgetc(f)) > 0);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 value[r] = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 while (value[--r] < 33) value[r] = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 if (decoder) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 size_t decodedSize;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 void *decoded = decoder(value, decdata, &decodedSize);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336 free(value);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337 value = (char*) decoded;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338 r = decodedSize;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
339 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340 r += 2;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 value = (char*) realloc(value, r);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
343
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
344 if (allocator.pool) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
345 void *pooledValue = allocator.malloc(allocator.pool, r);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 memcpy(pooledValue, value, r);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
347 free(value);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
348 value = (char*) pooledValue;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
349 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
351 ucx_map_cstr_put(map, key, value);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352 free(key);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
354
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
355 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 int ucx_map_store_enc(UcxMap *map, FILE *f,
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359 ucx_map_coder encoder, void *encdata) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360 UcxMapIterator iter = ucx_map_iterator(map);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361 char *k, *v;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
362 sstr_t key, value;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
363 int written;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
365 UCX_MAP_FOREACH(v, iter) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 k = (char*) iter.cur->key.data;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
367 key = sstr(k);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 if (encoder) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
369 size_t encodedSize;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
370 void *encoded = encoder(v, encdata, &encodedSize);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
371 value = sstrn((char*) encoded,encodedSize - 1);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372 } else {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373 value = sstr(v);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
376 written = 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
377 written += fwrite(key.ptr, 1, key.length, f);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 written += fwrite(" = ", 1, 3, f);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379 written += fwrite(value.ptr, 1, value.length, f);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
380 written += fwrite("\n", 1, 1, f);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
381
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
382 if (encoder) {
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383 free(value.ptr);
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
384 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 if (written != key.length + value.length + 4) return 1;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 }
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 return 0;
1bcaac272cdf added existing source code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390 }

mercurial