00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00039 #include "ctrump/common/intmap.h"
00040 #include "ctrump/common/mempool.h"
00041 #include <stdlib.h>
00042
00043 void
00044 ctrump_intmap_init(struct ctrump_intmap *map,
00045 int size)
00046 {
00047 int i;
00048 map->size = size;
00049 map->buckets = malloc(sizeof(struct ctrump_intmap_bucket)*size);
00050 map->pool = NULL;
00051
00052 for (i=0; i<size; i++) {
00053 map->buckets[i] = NULL;
00054 }
00055 }
00056
00057
00058 void
00059 ctrump_intmap_init_pool(struct ctrump_intmap *map,
00060 int size,
00061 struct ctrump_mempool *pool)
00062 {
00063 int i;
00064 map->size = size;
00065 map->buckets = ctrump_mempool_alloc(pool, sizeof(struct ctrump_intmap_bucket)*size);
00066 map->pool = pool;
00067
00068 for (i=0; i<size; i++) {
00069 map->buckets[i] = NULL;
00070 }
00071 }
00072
00073 static struct ctrump_intmap_bucket *
00074 ctrump_intmap_lookup_impl(struct ctrump_intmap *map,
00075 int *found,
00076 unsigned int key,
00077 int add)
00078 {
00079 unsigned int idx = key%map->size;
00080 struct ctrump_intmap_bucket **pp, *p;
00081
00082 pp = &map->buckets[idx];
00083 p = map->buckets[idx];
00084
00085 while (p) {
00086 if (p->key == key) {
00087 *found = 1;
00088 return p;
00089 }
00090 pp = &p->chain;
00091 p = p->chain;
00092 }
00093
00094 if (add) {
00095 if (map->pool) {
00096 p = ctrump_mempool_alloc(map->pool, sizeof(*p));
00097 } else {
00098 p = malloc(sizeof(*p));
00099 }
00100
00101 *pp = p;
00102 p->chain = NULL;
00103 p->key = key;
00104 }
00105
00106 *found = 0;
00107
00108 return p;
00109 }
00110
00111 struct ctrump_intmap_bucket *
00112 ctrump_intmap_lookup_add(struct ctrump_intmap *map,
00113 int *found,
00114 unsigned int key)
00115 {
00116 return ctrump_intmap_lookup_impl(map, found, key, 1);
00117 }
00118
00119 void *
00120 ctrump_intmap_lookup(struct ctrump_intmap *map,
00121 int *found,
00122 unsigned int key)
00123 {
00124 struct ctrump_intmap_bucket *b;
00125 b = ctrump_intmap_lookup_impl(map, found, key, 0);
00126
00127 if (b)
00128 return b->val;
00129
00130 return NULL;
00131 }
00132
00133 struct ctrump_intmap_bucket *
00134 ctrump_intmap_lookup_bucket(struct ctrump_intmap *map,
00135 int *found,
00136 unsigned int key)
00137 {
00138 return ctrump_intmap_lookup_impl(map, found, key, 0);
00139 }
00140
00141
00142 static void
00143 iter_next(struct ctrump_intmap_iterator *iter,
00144 struct ctrump_intmap *map,
00145 int begin)
00146 {
00147 int i;
00148 int n = map->size;
00149 for (i=begin; i<n; i++) {
00150 if (map->buckets[i]) {
00151 iter->buckets_index = i;
00152 iter->next = map->buckets[i];
00153 return;
00154 }
00155 }
00156
00157 iter->buckets_index = i;
00158 iter->next = NULL;
00159 }
00160
00161 void
00162 ctrump_intmap_iterator_begin(struct ctrump_intmap_iterator *iter,
00163 struct ctrump_intmap *map)
00164 {
00165 iter_next(iter, map, 0);
00166 }
00167
00168 int
00169 ctrump_intmap_iterator_next(struct ctrump_intmap_bucket **ret,
00170 struct ctrump_intmap_iterator *iter,
00171 struct ctrump_intmap *map)
00172 {
00173 struct ctrump_intmap_bucket *b;
00174 if (iter->next == NULL) {
00175 iter_next(iter, map, iter->buckets_index+1);
00176 if (iter->buckets_index >= map->size)
00177 return 0;
00178 }
00179
00180 b = iter->next;
00181 iter->next = b->chain;
00182
00183 *ret = b;
00184
00185 return 1;
00186 }
00187
00188 int
00189 ctrump_intmap_get_num_elem(struct ctrump_intmap *map)
00190 {
00191 int s = map->size, i;
00192 int nelem = 0;
00193 for (i=0; i<s; i++) {
00194 struct ctrump_intmap_bucket *b;
00195 b = map->buckets[i];
00196
00197 while (b) {
00198 nelem++;
00199 b = b->chain;
00200 }
00201 }
00202
00203 return nelem;
00204 }
00205
00206 static const int sizes[] = {
00207 5,
00208 17,
00209 41,
00210 79,
00211 149,
00212 251,
00213 421,
00214 683,
00215 1117,
00216 1823,
00217 2917,
00218 4679,
00219 7489,
00220 11867,
00221 18691,
00222 29443
00223 };
00224
00225 #define NELEM(a) (sizeof(a)/sizeof(a[0]))
00226
00227 void
00228 ctrump_intmap_resize_pool(struct ctrump_intmap *dest,
00229 const struct ctrump_intmap *src,
00230 struct ctrump_mempool *pool)
00231 {
00232 int nelem = 0;
00233 int i, bi;
00234 unsigned int new_size;
00235 int s = src->size;
00236 struct ctrump_intmap_bucket *buckets;
00237 for (i=0; i<s; i++) {
00238 struct ctrump_intmap_bucket *b;
00239 b = src->buckets[i];
00240
00241 while (b) {
00242 nelem++;
00243 b = b->chain;
00244 }
00245 }
00246
00247 if (nelem > 29443) {
00248 new_size = nelem;
00249 } else {
00250 for (i=0; i<NELEM(sizes); i++) {
00251 new_size = sizes[i];
00252 if (new_size >= nelem)
00253 break;
00254 }
00255 }
00256
00257 if (pool) {
00258 ctrump_intmap_init_pool(dest, new_size, pool);
00259 buckets = ctrump_mempool_alloc(pool, sizeof(struct ctrump_intmap_bucket)*nelem);
00260 } else {
00261 ctrump_intmap_init(dest, new_size);
00262 buckets = malloc(sizeof(struct ctrump_intmap_bucket)*nelem);
00263 }
00264
00265 bi = 0;
00266
00267 for (i=0; i<s; i++) {
00268 struct ctrump_intmap_bucket *b, *nb, *pb;
00269 b = src->buckets[i];
00270
00271 while (b) {
00272 unsigned int k;
00273 nb = &buckets[bi];
00274 bi++;
00275
00276 k = nb->key = b->key;
00277 nb->val = b->val;
00278
00279 pb = dest->buckets[k%new_size];
00280 nb->chain = pb;
00281 dest->buckets[k%new_size] = nb;
00282
00283 b = b->chain;
00284 }
00285 }
00286 }
00287
00288 void
00289 ctrump_intmap_free(struct ctrump_intmap *map)
00290 {
00291 int i;
00292 int s = map->size;
00293 for (i=0; i<s; i++) {
00294 struct ctrump_intmap_bucket *b, *chain;
00295 b = map->buckets[i];
00296
00297 while (b) {
00298 chain = b->chain;
00299 free(b);
00300 b = chain;
00301 }
00302 }
00303
00304 free(map->buckets);
00305 }