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 size_t _sample_hash(void *key, size_t size)
00228 {
00229 return (*((int *) key) % size);
00230 };
00231
00232 int _sample_comp(void *key1, void *key2)
00233 {
00234 int k1 = *((int *) key1),
00235 k2 = *((int *) key2);
00236
00237 return k1 < k2 ? -1 : ((k1 > k2)? 1 : 0);
00238 };
00239
00240 u_string_t *_sample_str(u_hmap_o_t *obj)
00241 {
00242 enum { MAX_OBJ_STR = 256 };
00243 char buf[MAX_OBJ_STR];
00244 u_string_t *s = NULL;
00245
00246 int key = *((int *) obj->key);
00247 char *val = (char *) obj->val;
00248
00249 dbg_err_if (u_snprintf(buf, MAX_OBJ_STR, "[%d:%s]", key, val));
00250 dbg_err_if (u_string_create(buf, strlen(buf)+1, &s));
00251
00252 return s;
00253
00254 err:
00255 return NULL;
00256 };
00257
00258
00259 u_hmap_o_t *_sample_obj(int key, const char *val)
00260 {
00261 u_hmap_o_t *new = NULL;
00262
00263 int *k = NULL;
00264 char *v = NULL;
00265
00266 k = (int *) malloc(sizeof(int));
00267 dbg_err_if (k == NULL);
00268 *k = key;
00269
00270 v = u_strdup(val);
00271 dbg_err_if (v == NULL);
00272
00273 new = u_hmap_o_new(k, v);
00274 dbg_err_if (new == NULL);
00275
00276 return new;
00277
00278 err:
00279 u_free(k);
00280 u_free(v);
00281
00282 return NULL;
00283 };
00284
00285 static int example_types_custom()
00286 {
00287 #define MAP_INSERT(hmap, k, v) \
00288 dbg_err_if ((obj = _sample_obj(k, v)) == NULL); \
00289 dbg_err_if (u_hmap_put(hmap, obj, NULL));
00290
00291 u_hmap_opts_t *opts = NULL;
00292 u_hmap_t *hmap = NULL;
00293 u_hmap_o_t *obj = NULL;
00294
00295 dbg("example_types_custom()");
00296
00297 dbg_err_if (u_hmap_opts_new(&opts));
00298 opts->options |= U_HMAP_OPTS_OWNSDATA | U_HMAP_OPTS_HASH_STRONG;
00299 opts->size = 3;
00300 opts->f_hash = &_sample_hash;
00301 opts->f_comp = &_sample_comp;
00302 opts->f_str = &_sample_str;
00303
00304 dbg_err_if (u_hmap_new(opts, &hmap));
00305
00306 MAP_INSERT(hmap, 2, "two");
00307 MAP_INSERT(hmap, 1, "one");
00308 MAP_INSERT(hmap, 4, "four");
00309 MAP_INSERT(hmap, 7, "seven");
00310 MAP_INSERT(hmap, 4, "four2");
00311 MAP_INSERT(hmap, 3, "three");
00312 MAP_INSERT(hmap, 6, "six");
00313 MAP_INSERT(hmap, 1, "one2");
00314 MAP_INSERT(hmap, 5, "five");
00315
00316 int x = 1;
00317 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00318 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00319 x++;
00320 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00321 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00322 x++;
00323 dbg_err_if (u_hmap_get(hmap, &x, &obj));
00324 dbg("hmap['%d'] = %s", *((int *) obj->key), (char *) obj->val);
00325
00326 u_hmap_dbg(hmap);
00327 u_hmap_opts_free(opts);
00328 u_hmap_free(hmap);
00329
00330 return 0;
00331 err:
00332 U_FREEF(opts, u_hmap_opts_free);
00333 U_FREEF(hmap, u_hmap_free);
00334
00335 return ~0;
00336 #undef MAP_INSERT
00337 }
00338
00339 static int test_resize()
00340 {
00341 enum { NUM_ELEMS = 100000, MAX_STR = 256 };
00342 u_hmap_opts_t *opts = NULL;
00343 u_hmap_t *hmap = NULL;
00344 u_hmap_o_t *obj = NULL;
00345 int i = 0;
00346 char key[MAX_STR],
00347 val[MAX_STR];
00348
00349 dbg("test_resize()");
00350
00351
00352 dbg_err_if (u_hmap_opts_new(&opts));
00353 opts->size = 3;
00354 dbg_err_if (u_hmap_new(opts, &hmap));
00355
00356
00357 for (i = 0; i < NUM_ELEMS; ++i) {
00358 u_snprintf(key, MAX_STR, "key%d", i);
00359 u_snprintf(val, MAX_STR, "val%d", i);
00360 dbg_err_if (u_hmap_put(hmap, u_hmap_o_new(u_strdup(key),
00361 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),
00408 u_strdup(val)), NULL));
00409 }
00410
00411 for (i = 0; i < NUM_ELEMS; ++i) {
00412 u_snprintf(key, MAX_STR, "key%d", i);
00413 dbg_err_if (u_hmap_del(hmap, key, &obj));
00414 u_hmap_o_free(obj->key);
00415 u_hmap_o_free(obj->val);
00416 u_hmap_o_free(obj);
00417 }
00418
00419
00420 u_hmap_opts_free(opts);
00421 u_hmap_free(hmap);
00422
00423 return 0;
00424
00425 err:
00426 U_FREEF(opts, u_hmap_opts_free);
00427 U_FREEF(hmap, u_hmap_free);
00428
00429 return ~0;
00430 }
00431
00432 U_TEST_MODULE(hmap)
00433 {
00434
00435 U_TEST_RUN( example_static );
00436 U_TEST_RUN( example_dynamic_own_hmap );
00437 U_TEST_RUN( example_dynamic_own_user );
00438 U_TEST_RUN( example_no_overwrite );
00439 U_TEST_RUN( example_types_custom );
00440
00441
00442 U_TEST_RUN( test_resize );
00443 U_TEST_RUN( test_linear );
00444
00445 return 0;
00446 }