00001 #include <u/libu.h>
00002 #include <string.h>
00003
00004
00005 static int example_static()
00006 {
00007 u_hmap_t *hmap = NULL;
00008 u_hmap_o_t *obj = NULL;
00009 int fibonacci[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
00010
00011 dbg("example_static()");
00012
00013
00014 dbg_err_if (u_hmap_new(NULL, &hmap));
00015
00016
00017 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new("first", &fibonacci[0]), NULL));
00018 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new("fifth", &fibonacci[4]), NULL));
00019 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new("last",
00020 &fibonacci[(sizeof(fibonacci)/sizeof(int))-1]), NULL));
00021
00022
00023 dbg_err_if (u_hmap_get(hmap, "last", &obj));
00024 dbg("hmap['%s'] = %d", (char *) obj->key, *((int *) obj->val));
00025 dbg_err_if (u_hmap_get(hmap, "fifth", &obj));
00026 dbg("hmap['%s'] = %d", (char *) obj->key, *((int *) obj->val));
00027 dbg_err_if (u_hmap_get(hmap, "first", &obj));
00028 dbg("hmap['%s'] = %d", (char *) obj->key, *((int *) obj->val));
00029
00030
00031 dbg_err_if (u_hmap_del(hmap, "fifth", &obj));
00032 u_hmap_o_free(obj);
00033
00034
00035 dbg_err_if (u_hmap_get(hmap, "fifth", &obj) == 0);
00036
00037
00038 dbg_err_if (u_hmap_del(hmap, "last", &obj));
00039 u_hmap_o_free(obj);
00040 dbg_err_if (u_hmap_del(hmap, "first", &obj));
00041 u_hmap_o_free(obj);
00042
00043
00044 u_hmap_free(hmap);
00045
00046 return 0;
00047 err:
00048 U_FREEF(hmap, u_hmap_free);
00049
00050 return ~0;
00051 }
00052
00053 static int example_dynamic_own_hmap()
00054 {
00055 u_hmap_opts_t *opts = NULL;
00056 u_hmap_t *hmap = NULL;
00057 u_hmap_o_t *obj = NULL;
00058
00059 dbg("example_dynamic_own_hmap()");
00060
00061
00062 dbg_err_if (u_hmap_opts_new(&opts));
00063
00064 opts->options |= U_HMAP_OPTS_OWNSDATA;
00065 dbg_err_if (u_hmap_new(opts, &hmap));
00066
00067
00068 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("english"),
00069 (void *) u_strdup("Hello world!")), NULL));
00070 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("italian"),
00071 (void *) u_strdup("Ciao mondo!")), NULL));
00072 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("german"),
00073 (void *) u_strdup("Hallo Welt!")), NULL));
00074
00075
00076 dbg_err_if (u_hmap_get(hmap, "italian", &obj));
00077 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00078 dbg_err_if (u_hmap_get(hmap, "german", &obj));
00079 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00080 dbg_err_if (u_hmap_get(hmap, "english", &obj));
00081 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00082
00083
00084 dbg_err_if (u_hmap_del(hmap, "german", NULL));
00085
00086
00087 dbg_err_if (u_hmap_get(hmap, "german", &obj) == 0);
00088
00089
00090 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("german"),
00091 (void *) u_strdup("Auf Wiedersehen!")), NULL));
00092 dbg_err_if (u_hmap_get(hmap, "german", &obj));
00093 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00094
00095
00096 u_hmap_dbg(hmap);
00097 u_hmap_opts_free(opts);
00098 u_hmap_free(hmap);
00099
00100 return 0;
00101
00102 err:
00103 U_FREEF(opts, u_hmap_opts_free);
00104 U_FREEF(hmap, u_hmap_free);
00105
00106 return ~0;
00107 }
00108
00109 static int example_dynamic_own_user()
00110 {
00111 u_hmap_t *hmap = NULL;
00112 u_hmap_o_t *obj = NULL;
00113
00114 #define OBJ_FREE(obj) \
00115 if (obj) { \
00116 u_free(obj->key); \
00117 u_free(obj->val); \
00118 u_hmap_o_free(obj); \
00119 obj = NULL; \
00120 }
00121
00122 dbg("example_dynamic_own_user()");
00123
00124
00125 dbg_err_if (u_hmap_new(NULL, &hmap));
00126
00127
00128 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("english"),
00129 (void *) u_strdup("Hello world!")), &obj));
00130 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("italian"),
00131 (void *) u_strdup("Ciao mondo!")), &obj));
00132 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("german"),
00133 (void *) u_strdup("Hallo Welt!")), &obj));
00134
00135
00136 dbg_err_if (u_hmap_get(hmap, "italian", &obj));
00137 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00138 dbg_err_if (u_hmap_get(hmap, "german", &obj));
00139 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00140 dbg_err_if (u_hmap_get(hmap, "english", &obj));
00141 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00142
00143
00144 dbg_err_if (u_hmap_del(hmap, "german", &obj));
00145 OBJ_FREE(obj);
00146
00147
00148 dbg_err_if (u_hmap_get(hmap, "german", &obj) == 0);
00149
00150
00151 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("german"),
00152 (void *) u_strdup("Auf Wiedersehen!")), NULL));
00153 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new((void *) u_strdup("german"),
00154 (void *) u_strdup("Auf Wiedersehen2!")), &obj));
00155 OBJ_FREE(obj);
00156 dbg_err_if (u_hmap_get(hmap, "german", &obj));
00157 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00158
00159 u_hmap_del(hmap, "italian", &obj);
00160 OBJ_FREE(obj);
00161 u_hmap_del(hmap, "german", &obj);
00162 OBJ_FREE(obj);
00163 u_hmap_del(hmap, "english", &obj);
00164 OBJ_FREE(obj);
00165
00166
00167 u_hmap_free(hmap);
00168
00169 return 0;
00170
00171 err:
00172 U_FREEF(hmap, u_hmap_free);
00173
00174 return ~0;
00175 }
00176
00177 static int example_no_overwrite()
00178 {
00179 #define MAP_INSERT(hmap, key, val, obj) \
00180 switch (u_hmap_put(hmap, u_hmap_o_new(key, val), &obj)) { \
00181 case U_HMAP_ERR_NONE: \
00182 break; \
00183 case U_HMAP_ERR_EXISTS: \
00184 u_hmap_o_free(obj); \
00185 break; \
00186 case U_HMAP_ERR_FAIL: \
00187 goto err; \
00188 }
00189
00190 u_hmap_opts_t *opts = NULL;
00191 u_hmap_t *hmap = NULL;
00192 u_hmap_o_t *obj = NULL;
00193
00194 dbg("example_no_overwrite()");
00195
00196
00197 dbg_err_if (u_hmap_opts_new(&opts));
00198
00199 opts->options |= U_HMAP_OPTS_NO_OVERWRITE;
00200 dbg_err_if (u_hmap_new(opts, &hmap));
00201
00202
00203 MAP_INSERT(hmap, "A", "A1", obj);
00204 MAP_INSERT(hmap, "A", "A2", obj);
00205 MAP_INSERT(hmap, "A", "A3", obj);
00206
00207
00208 dbg_err_if (u_hmap_get(hmap, "A", &obj));
00209 dbg("hmap['%s'] = %s", (char *) obj->key, (char *) obj->val);
00210 dbg_err_if (u_hmap_del(hmap, "A", &obj));
00211 u_hmap_o_free(obj);
00212
00213
00214 u_hmap_opts_free(opts);
00215 u_hmap_free(hmap);
00216
00217 return 0;
00218
00219 err:
00220 U_FREEF(opts, u_hmap_opts_free);
00221 U_FREEF(hmap, u_hmap_free);
00222
00223 return ~0;
00224 #undef MAP_INSERT
00225 }
00226
00227
00228 static int example_types_custom()
00229 {
00230 #define MAP_INSERT(hmap, k, v) \
00231 dbg_err_if ((obj = _sample_obj(k, v)) == NULL); \
00232 dbg_err_if (u_hmap_put(hmap, obj, NULL));
00233
00234 size_t _sample_hash(void *key, size_t size)
00235 {
00236 return (*((int *) key) % size);
00237 };
00238
00239 int _sample_comp(void *key1, void *key2)
00240 {
00241 int k1 = *((int *) key1),
00242 k2 = *((int *) key2);
00243
00244 return k1 < k2 ? -1 : ((k1 > k2)? 1 : 0);
00245 };
00246
00247 u_string_t *_sample_str(u_hmap_o_t *obj)
00248 {
00249 enum { MAX_OBJ_STR = 256 };
00250 char buf[MAX_OBJ_STR];
00251 u_string_t *s = NULL;
00252
00253 int key = *((int *) obj->key);
00254 char *val = (char *) obj->val;
00255
00256 dbg_err_if (u_snprintf(buf, MAX_OBJ_STR, "[%d:%s]", key, val));
00257 dbg_err_if (u_string_create(buf, strlen(buf)+1, &s));
00258
00259 return s;
00260
00261 err:
00262 return NULL;
00263 };
00264
00265
00266 u_hmap_o_t *_sample_obj(int key, const char *val)
00267 {
00268 u_hmap_o_t *new = NULL;
00269
00270 int *k = NULL;
00271 char *v = NULL;
00272
00273 k = (int *) malloc(sizeof(int));
00274 dbg_err_if (k == NULL);
00275 *k = key;
00276
00277 v = u_strdup(val);
00278 dbg_err_if (v == NULL);
00279
00280 new = u_hmap_o_new(k, v);
00281 dbg_err_if (new == NULL);
00282
00283 return new;
00284
00285 err:
00286 u_free(k);
00287 u_free(v);
00288
00289 return NULL;
00290 };
00291
00292 u_hmap_opts_t *opts = NULL;
00293 u_hmap_t *hmap = NULL;
00294 u_hmap_o_t *obj = NULL;
00295
00296 dbg("example_types_custom()");
00297
00298 dbg_err_if (u_hmap_opts_new(&opts));
00299 opts->options |= U_HMAP_OPTS_OWNSDATA | U_HMAP_OPTS_HASH_STRONG;
00300 opts->size = 3;
00301 opts->f_hash = &_sample_hash;
00302 opts->f_comp = &_sample_comp;
00303 opts->f_str = &_sample_str;
00304
00305 dbg_err_if (u_hmap_new(opts, &hmap));
00306
00307 MAP_INSERT(hmap, 2, "two");
00308 MAP_INSERT(hmap, 1, "one");
00309 MAP_INSERT(hmap, 4, "four");
00310 MAP_INSERT(hmap, 7, "seven");
00311 MAP_INSERT(hmap, 4, "four2");
00312 MAP_INSERT(hmap, 3, "three");
00313 MAP_INSERT(hmap, 6, "six");
00314 MAP_INSERT(hmap, 1, "one2");
00315 MAP_INSERT(hmap, 5, "five");
00316
00317 int x = 1;
00318 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00319 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00320 x++;
00321 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00322 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00323 x++;
00324 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00325 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00326
00327 u_hmap_dbg(hmap);
00328 u_hmap_opts_free(opts);
00329 u_hmap_free(hmap);
00330
00331 return 0;
00332 err:
00333 U_FREEF(opts, u_hmap_opts_free);
00334 U_FREEF(hmap, u_hmap_free);
00335
00336 return ~0;
00337 #undef MAP_INSERT
00338 }
00339
00340 static int test_resize()
00341 {
00342 enum { NUM_ELEMS = 100000, MAX_STR = 256 };
00343 u_hmap_opts_t *opts = NULL;
00344 u_hmap_t *hmap = NULL;
00345 u_hmap_o_t *obj = NULL;
00346 int i = 0;
00347 char key[MAX_STR],
00348 val[MAX_STR];
00349
00350 dbg("test_resize()");
00351
00352
00353 dbg_err_if (u_hmap_opts_new(&opts));
00354 opts->size = 3;
00355 dbg_err_if (u_hmap_new(opts, &hmap));
00356
00357
00358 for (i = 0; i < NUM_ELEMS; ++i) {
00359 u_snprintf(key, MAX_STR, "key%d", i);
00360 u_snprintf(val, MAX_STR, "val%d", i);
00361 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new(u_strdup(key), u_strdup(val)), NULL));
00362 }
00363
00364 for (i = 0; i < NUM_ELEMS; ++i) {
00365 u_snprintf(key, MAX_STR, "key%d", i);
00366 dbg_err_if (u_hmap_del(hmap, key, &obj));
00367 u_hmap_o_free(obj->key);
00368 u_hmap_o_free(obj->val);
00369 u_hmap_o_free(obj);
00370 }
00371
00372
00373 u_hmap_opts_free(opts);
00374 u_hmap_free(hmap);
00375
00376 return 0;
00377
00378 err:
00379 U_FREEF(opts, u_hmap_opts_free);
00380 U_FREEF(hmap, u_hmap_free);
00381
00382 return ~0;
00383 }
00384
00385 static int test_linear()
00386 {
00387 enum { NUM_ELEMS = 100000, MAX_STR = 256 };
00388 u_hmap_opts_t *opts = NULL;
00389 u_hmap_t *hmap = NULL;
00390 u_hmap_o_t *obj = NULL;
00391 int i = 0;
00392 char key[MAX_STR],
00393 val[MAX_STR];
00394
00395 dbg("test_linear()");
00396
00397
00398 dbg_err_if (u_hmap_opts_new(&opts));
00399 opts->size = 1000;
00400 opts->type = U_HMAP_TYPE_LINEAR;
00401 dbg_err_if (u_hmap_new(opts, &hmap));
00402
00403
00404 for (i = 0; i < NUM_ELEMS; ++i) {
00405 u_snprintf(key, MAX_STR, "key%d", i);
00406 u_snprintf(val, MAX_STR, "val%d", i);
00407 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new(u_strdup(key), u_strdup(val)), NULL));
00408 }
00409
00410 for (i = 0; i < NUM_ELEMS; ++i) {
00411 u_snprintf(key, MAX_STR, "key%d", i);
00412 dbg_err_if (u_hmap_del(hmap, key, &obj));
00413 u_hmap_o_free(obj->key);
00414 u_hmap_o_free(obj->val);
00415 u_hmap_o_free(obj);
00416 }
00417
00418
00419 u_hmap_opts_free(opts);
00420 u_hmap_free(hmap);
00421
00422 return 0;
00423
00424 err:
00425 U_FREEF(opts, u_hmap_opts_free);
00426 U_FREEF(hmap, u_hmap_free);
00427
00428 return ~0;
00429 }
00430
00431 U_TEST_MODULE(hmap)
00432 {
00433
00434 U_TEST_RUN( example_static );
00435 U_TEST_RUN( example_dynamic_own_hmap );
00436 U_TEST_RUN( example_dynamic_own_user );
00437 U_TEST_RUN( example_no_overwrite );
00438 U_TEST_RUN( example_types_custom );
00439
00440
00441 U_TEST_RUN( test_resize );
00442 U_TEST_RUN( test_linear );
00443
00444 return 0;
00445 }