Main Page | Modules | Data Structures | File List | Data Fields

hmap.c

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     /* initialise hmap with no options - user owns data by default */
00014     dbg_err_if (u_hmap_new(NULL, &hmap));
00015 
00016     /* insert some sample elements */
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     /* retrieve and print values to dbgsole */
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     /* remove an element and replace it */
00031     dbg_err_if (u_hmap_del(hmap, "fifth", &obj)); 
00032     u_hmap_o_free(obj);
00033     
00034     /* check that it has been deleted */
00035     dbg_err_if (u_hmap_get(hmap, "fifth", &obj) == 0); 
00036 
00037     /* delete the other two elements */
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     /* free hmap and options */
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     /* initialise options and hmap */
00062     dbg_err_if (u_hmap_opts_new(&opts));
00063     /* hmap owns both keys and data */
00064     opts->options |= U_HMAP_OPTS_OWNSDATA;
00065     dbg_err_if (u_hmap_new(opts, &hmap));
00066 
00067     /* insert some sample elements */
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     /* retrieve and print values to console */
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     /* remove an element and replace it */
00084     dbg_err_if (u_hmap_del(hmap, "german", NULL)); 
00085 
00086     /* check that it has been deleted */
00087     dbg_err_if (u_hmap_get(hmap, "german", &obj) == 0); 
00088 
00089     /* replace with a new element and print it */
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     /* free hmap (options and elements are freed automatically) */
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     /* hmap owns both keys and data */
00125     dbg_err_if (u_hmap_new(NULL, &hmap));
00126 
00127     /* insert some sample elements */
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     /* retrieve and print values to console */
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     /* remove an element and replace it */
00144     dbg_err_if (u_hmap_del(hmap, "german", &obj)); 
00145     OBJ_FREE(obj);
00146 
00147     /* check that it has been deleted */
00148     dbg_err_if (u_hmap_get(hmap, "german", &obj) == 0); 
00149 
00150     /* replace with a new element and print it */
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     /* free hmap (options and elements are freed automatically) */
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     /* initialise options and hmap */
00197     dbg_err_if (u_hmap_opts_new(&opts));
00198     /* hmap owns both keys and data */
00199     opts->options |= U_HMAP_OPTS_NO_OVERWRITE;
00200     dbg_err_if (u_hmap_new(opts, &hmap));
00201 
00202     /* insert some sample elements with the same key */
00203     MAP_INSERT(hmap, "A", "A1", obj);
00204     MAP_INSERT(hmap, "A", "A2", obj);
00205     MAP_INSERT(hmap, "A", "A3", obj);
00206 
00207     /* retrieve and print values to console */
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     /* free hmap and opts */
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 /* Allocate (key, value) pair dynamically */
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     /* initialise hmap with no options - user owns data by default */
00352     dbg_err_if (u_hmap_opts_new(&opts));
00353     opts->size = 3;
00354     dbg_err_if (u_hmap_new(opts, &hmap));
00355 
00356     /* insert some sample elements */
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     /* free hmap and options */
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     /* initialise hmap with no options - user owns data by default */
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     /* insert some sample elements */
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     /* free hmap and options */
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     /* examples */
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     /* tests */
00442     U_TEST_RUN( test_resize );
00443     U_TEST_RUN( test_linear );
00444 
00445     return 0;
00446 }

←Products
© 2005-2008 - KoanLogic S.r.l. - All rights reserved