test/hmap.c

00001 #include <u/libu.h>
00002 #include <string.h>
00003 
00004 int test_suite_hmap_register (u_test_t *t);
00005 
00006 static size_t __sample_hash (const void *key, size_t size);
00007 static int __sample_comp(const void *key1, const void *key2);
00008 static u_string_t *__sample_str(u_hmap_o_t *obj);
00009 
00010 static int example_easy_basic (u_test_case_t *tc)
00011 {
00012     u_hmap_opts_t *opts = NULL;
00013     u_hmap_t *hmap = NULL;
00014 
00015     u_test_err_if (u_hmap_opts_new(&opts));
00016     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00017       
00018     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00019 
00020     u_test_err_if (u_hmap_easy_put(hmap, "jack", (const void *) ":S"));
00021     u_test_err_if (u_hmap_easy_put(hmap, "jill", (const void *) ":)))"));
00022 
00023     u_test_case_printf(tc, "jack is %s and jill is %s",
00024       (const char *) u_hmap_easy_get(hmap, "jack"),
00025       (const char *) u_hmap_easy_get(hmap, "jill"));
00026 
00027     u_hmap_easy_free(hmap);
00028     u_hmap_opts_free(opts);
00029 
00030     return U_TEST_SUCCESS;
00031 err:
00032     U_FREEF(hmap, u_hmap_easy_free);
00033     U_FREEF(opts, u_hmap_opts_free);
00034 
00035     return U_TEST_FAILURE;
00036 }
00037 
00038 static int example_easy_static (u_test_case_t *tc)
00039 {
00040     u_hmap_opts_t *opts = NULL;
00041     u_hmap_t *hmap = NULL;
00042 
00043     u_dbg("example_easy_static()");
00044 
00045     u_test_err_if (u_hmap_opts_new(&opts));
00046 
00047     /* no free function needed for static data */
00048     u_test_err_if (u_hmap_opts_set_val_freefunc(opts, NULL));
00049     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00050 
00051     u_test_err_if (u_hmap_easy_put(hmap, "0", "zero"));
00052     u_test_err_if (u_hmap_easy_put(hmap, "1", "one"));
00053     u_test_err_if (u_hmap_easy_put(hmap, "2", "two"));
00054     u_test_err_if (u_hmap_easy_put(hmap, "3", "three"));
00055 
00056     /* value that doesn't exist */
00057     u_test_err_if (u_hmap_easy_get(hmap, "4") != NULL);
00058 
00059     /* test deletion */
00060     u_test_err_if (u_hmap_easy_del(hmap, "3"));
00061     u_test_err_if (u_hmap_easy_get(hmap, "3") != NULL);
00062     u_test_err_if (u_hmap_easy_put(hmap, "3", "THREE"));
00063 
00064 #ifdef DEBUG_HEAVY
00065     u_hmap_dbg(hmap);
00066 #endif
00067 
00068     /* print out all values */
00069     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "0"), "zero") != 0);
00070     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "1"), "one") != 0);
00071     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "2"), "two") != 0);
00072     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "3"), "THREE") != 0);
00073 
00074     /* test overwrite - should fail */
00075     u_test_err_if (u_hmap_easy_put(hmap, "2", "TWO") == 0);
00076     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "2"), "two") != 0);
00077 
00078     U_FREEF(hmap, u_hmap_easy_free);
00079 
00080     /* make a new hmap that _allows_ overwrite */
00081     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_NO_OVERWRITE));
00082     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00083 
00084     /* put elements */
00085     u_test_err_if (u_hmap_easy_put(hmap, "a", "alpha"));
00086     u_test_err_if (u_hmap_easy_put(hmap, "b", "beta"));
00087     u_test_err_if (u_hmap_easy_put(hmap, "a", "ALPHA"));
00088 
00089 #ifdef DEBUG_HEAVY
00090     u_hmap_dbg(hmap);
00091 #endif
00092 
00093     /* check elements */
00094     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "a"), "ALPHA") != 0);
00095     u_test_err_if (strcmp(u_hmap_easy_get(hmap, "b"), "beta") != 0);
00096     
00097     /* free hmap (options and elements are freed automatically) */
00098     u_hmap_easy_free(hmap);
00099     u_hmap_opts_free(opts);
00100 
00101     return U_TEST_SUCCESS;
00102 err:
00103     U_FREEF(hmap, u_hmap_easy_free);
00104     U_FREEF(opts, u_hmap_opts_free);
00105 
00106     return U_TEST_FAILURE;
00107 }
00108 
00109 struct mystruct_s {
00110     char *a;
00111     char *b;
00112 };
00113 typedef struct mystruct_s mystruct_t;
00114 
00115 static mystruct_t *mystruct_create (void);
00116 static void mystruct_free (void *val);
00117 
00118 static void mystruct_free (void *val)
00119 {
00120     mystruct_t *mystruct = (mystruct_t *) val;
00121 
00122     if (val == NULL)
00123         return;
00124 
00125     u_free(mystruct->a);
00126     u_free(mystruct->b);
00127     u_free(mystruct);
00128 }
00129 
00130 static mystruct_t *mystruct_create (void)
00131 {
00132     mystruct_t *myval = NULL;
00133 
00134     dbg_err_if ((myval = (mystruct_t *) u_zalloc(sizeof(mystruct_t))) == NULL);
00135     dbg_err_if ((myval->a = strdup("first string")) == NULL);
00136     dbg_err_if ((myval->b = strdup("second string")) == NULL);
00137 
00138     return myval;
00139 err:
00140     U_FREEF(myval, mystruct_free);
00141 
00142     return NULL;
00143 }
00144 
00145 static int example_easy_dynamic (u_test_case_t *tc)
00146 {
00147     u_hmap_opts_t *opts = NULL;
00148     u_hmap_t *hmap = NULL;
00149     mystruct_t *mystruct;
00150 
00151     u_dbg("example_easy_dynamic()");
00152 
00153     u_test_err_if (u_hmap_opts_new(&opts));
00154 
00155     /* setup custom free function */
00156     u_test_err_if (u_hmap_opts_set_val_freefunc(opts, &mystruct_free));
00157     /* no string function for custom object */
00158     u_test_err_if (u_hmap_opts_set_strfunc(opts, NULL));
00159 
00160     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00161 
00162     /* insert 3 objects */
00163     u_test_err_if (u_hmap_easy_put(hmap, "a", mystruct_create()));
00164     u_test_err_if (u_hmap_easy_put(hmap, "b", mystruct_create()));
00165     u_test_err_if (u_hmap_easy_put(hmap, "c", mystruct_create()));
00166 
00167     /* test overwrite - should fail */
00168     u_test_err_if (u_hmap_easy_put(hmap, "b", mystruct_create()) == 0);
00169 
00170 #ifdef DEBUG_HEAVY
00171     u_hmap_dbg(hmap);
00172 #endif
00173 
00174     /* check a value */
00175     u_test_err_if ((mystruct = u_hmap_easy_get(hmap, "a")) == NULL);
00176     u_test_err_if (strcmp(mystruct->a, "first string") != 0);
00177     u_test_err_if (strcmp(mystruct->b, "second string") != 0);
00178     
00179     /* internal objects freed automatically using custom function */
00180     u_hmap_easy_free(hmap);
00181     u_hmap_opts_free(opts);
00182 
00183     return U_TEST_SUCCESS;
00184 err:
00185     U_FREEF(hmap, u_hmap_easy_free);
00186     U_FREEF(opts, u_hmap_opts_free);
00187 
00188     return U_TEST_FAILURE;
00189 }
00190 
00191 static size_t __sample_hash(const void *key, size_t size)
00192 {
00193     return (*((const int *) key) % size);
00194 }
00195 
00196 static int __sample_comp(const void *key1, const void *key2)
00197 {
00198     int k1 = *((const int *) key1),
00199         k2 = *((const int *) key2);
00200     
00201     return k1 < k2 ? -1 : ((k1 > k2)? 1 : 0);
00202 }
00203 
00204 static u_string_t *__sample_str(u_hmap_o_t *obj)
00205 {
00206     enum { MAX_OBJ_STR = 256 };
00207     char buf[MAX_OBJ_STR];
00208     u_string_t *s = NULL;
00209 
00210     int key = *((int *) u_hmap_o_get_key(obj));
00211     char *val = (char *) u_hmap_o_get_val(obj);
00212 
00213     dbg_err_if (u_snprintf(buf, MAX_OBJ_STR, "[%d:%s]", key, val));
00214     dbg_err_if (u_string_create(buf, strlen(buf)+1, &s));
00215 
00216     return s;
00217 
00218 err:
00219     return NULL;
00220 }
00221 
00222 struct mystruct2_s {
00223     char c;
00224     int x;
00225     double d;
00226 };
00227 typedef struct mystruct2_s mystruct2_t;
00228 
00229 static int example_easy_opaque (u_test_case_t *tc)
00230 {
00231     enum { 
00232         VAL_SZ = sizeof(mystruct2_t),
00233         ELEMS_NUM = 4
00234     };
00235     u_hmap_opts_t *opts = NULL;
00236     u_hmap_t *hmap = NULL;
00237     const char *keys[] = { "!@#", "$%^", "&*(", "()_" };
00238     mystruct2_t vals[] = { { 'a', 1, 1.1 }, { 'b', 2, 2.2 }, 
00239         { 'c', 3, 3.3 }, { 'd', 4, 4.4 } };
00240     mystruct2_t *pval;
00241     int i;
00242 
00243     u_dbg("example_easy_opaque()");
00244 
00245     u_test_err_if (u_hmap_opts_new(&opts));
00246 
00247     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_OPAQUE));
00248     u_test_err_if (u_hmap_opts_set_val_sz(opts, VAL_SZ));
00249 
00250     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00251 
00252     /* insert elements */
00253     for (i = 0 ; i < ELEMS_NUM; i++) 
00254         u_test_err_if (u_hmap_easy_put(hmap, keys[i], &vals[i]));
00255 
00256 #ifdef DEBUG_HEAVY
00257     u_hmap_dbg(hmap);
00258 #endif
00259 
00260     /* check elements */
00261     for (i = 0; i < ELEMS_NUM; i++) {
00262 
00263         pval = u_hmap_easy_get(hmap, keys[i]);
00264         u_test_err_if (pval == NULL);
00265 
00266         u_test_err_if ((pval->c != vals[i].c) ||
00267                 (pval->x != vals[i].x) ||
00268                 (pval->d != vals[i].d));
00269     }
00270 
00271     /* free hmap (options and elements are freed automatically) */
00272     u_hmap_easy_free(hmap);
00273     u_hmap_opts_free(opts);
00274 
00275     return U_TEST_SUCCESS;
00276 err:
00277     U_FREEF(hmap, u_hmap_free);
00278     U_FREEF(opts, u_hmap_opts_free);
00279 
00280     return U_TEST_FAILURE;
00281 }
00282 
00283 static int example_static (u_test_case_t *tc)
00284 {
00285     u_hmap_opts_t *opts = NULL;
00286     u_hmap_t *hmap = NULL;
00287     u_hmap_o_t *obj = NULL;
00288     int fibonacci[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
00289 
00290     u_dbg("example_static()");
00291 
00292     u_test_err_if (u_hmap_opts_new(&opts));
00293 
00294     /* hmap owns data by default - change it */
00295     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_OWNSDATA));
00296 
00297     u_test_err_if (u_hmap_new(opts, &hmap));
00298 
00299     /* insert some sample elements */
00300     u_test_err_if (u_hmap_put(hmap, 
00301                 u_hmap_o_new(hmap, "first", &fibonacci[0]), NULL));
00302     u_test_err_if (u_hmap_put(hmap, 
00303                 u_hmap_o_new(hmap, "fifth", &fibonacci[4]), NULL)); 
00304     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, "last", 
00305                 &fibonacci[(sizeof(fibonacci)/sizeof(int))-1]), NULL));
00306 
00307     /* retrieve and print values to dbg */
00308     u_test_err_if (u_hmap_get(hmap, "last", &obj)); 
00309     u_dbg("hmap['%s'] = %d", (char *) u_hmap_o_get_key(obj), 
00310             *((int *) u_hmap_o_get_val(obj)));
00311     u_test_err_if (u_hmap_get(hmap, "fifth", &obj)); 
00312     u_dbg("hmap['%s'] = %d", (char *) u_hmap_o_get_key(obj), 
00313             *((int *) u_hmap_o_get_val(obj))); 
00314     u_test_err_if (u_hmap_get(hmap, "first", &obj)); 
00315     u_dbg("hmap['%s'] = %d", (char *) u_hmap_o_get_key(obj), 
00316             *((int *) u_hmap_o_get_val(obj)));
00317     
00318     u_hmap_dbg(hmap);
00319 
00320     /* remove an element and replace it */
00321     u_test_err_if (u_hmap_del(hmap, "fifth", &obj)); 
00322     u_hmap_o_free(obj);
00323     
00324     /* check that it has been deleted */
00325     u_test_err_if (u_hmap_get(hmap, "fifth", &obj) == 0); 
00326 
00327     /* delete the other two elements */
00328     u_test_err_if (u_hmap_del(hmap, "last", &obj)); 
00329     u_hmap_o_free(obj);
00330     u_test_err_if (u_hmap_del(hmap, "first", &obj)); 
00331     u_hmap_o_free(obj);
00332 
00333     /* free hmap and options */
00334     u_hmap_free(hmap);
00335     u_hmap_opts_free(opts);
00336     
00337     return U_TEST_SUCCESS;
00338 err:
00339     U_FREEF(hmap, u_hmap_free);
00340     U_FREEF(opts, u_hmap_opts_free);
00341 
00342     return U_TEST_FAILURE;
00343 }
00344 
00345 static int example_dynamic_own_hmap (u_test_case_t *tc)
00346 {
00347     u_hmap_opts_t *opts = NULL;
00348     u_hmap_t *hmap = NULL;
00349     u_hmap_o_t *obj = NULL;
00350 
00351     u_dbg("example_dynamic_own_hmap()");
00352 
00353     u_test_err_if (u_hmap_opts_new(&opts));
00354 
00355     /* objects don't need to be freed - same as default:
00356     u_test_err_if (u_hmap_opts_set_freefunc(opts, NULL));
00357     */
00358 
00359     /* hmap owns both keys and data - allow overwrite */
00360     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00361     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_NO_OVERWRITE));
00362     u_test_err_if (u_hmap_new(opts, &hmap));
00363 
00364     /* insert some sample elements */
00365     u_test_err_if (u_hmap_put(hmap, 
00366                 u_hmap_o_new(hmap, "EN", "Hello world!"), NULL));
00367     u_test_err_if (u_hmap_put(hmap, 
00368                 u_hmap_o_new(hmap, "IT", "Ciao mondo!"), NULL));
00369     u_test_err_if (u_hmap_put(hmap, 
00370                 u_hmap_o_new(hmap, "DE", "Hallo Welt!"), NULL));
00371 
00372     /* retrieve and print values to console */
00373     u_test_err_if (u_hmap_get(hmap, "DE", &obj)); 
00374     u_test_err_if (u_hmap_get(hmap, "EN", &obj)); 
00375 
00376     /* remove an element and replace it */
00377     u_test_err_if (u_hmap_del(hmap, "DE", NULL)); 
00378     u_test_err_if (u_hmap_put(hmap, 
00379                 u_hmap_o_new(hmap, "DE", "Auf Wiedersehen!"), NULL));
00380     u_test_err_if (u_hmap_get(hmap, "DE", &obj)); 
00381 
00382     /* check some values */
00383     u_test_err_if (u_hmap_get(hmap, "IT", &obj)); 
00384     u_test_err_if (strcmp(u_hmap_o_get_val(obj), "Ciao mondo!") != 0);
00385     u_test_err_if (u_hmap_get(hmap, "DE", &obj)); 
00386     u_test_err_if (strcmp(u_hmap_o_get_val(obj), "Auf Wiedersehen!") != 0);
00387 
00388     /* free hmap (options and elements are freed automatically) */
00389     u_hmap_free(hmap);
00390     u_hmap_opts_free(opts);
00391 
00392     return U_TEST_SUCCESS;
00393 
00394 err:
00395     U_FREEF(hmap, u_hmap_free);
00396     U_FREEF(opts, u_hmap_opts_free);
00397 
00398     return U_TEST_FAILURE;
00399 }
00400 
00401 static int example_dynamic_own_user (u_test_case_t *tc)
00402 {
00403     u_hmap_opts_t *opts = NULL;
00404     u_hmap_t *hmap = NULL;
00405     u_hmap_o_t *obj = NULL;
00406 
00407 #define OBJ_FREE(obj) \
00408     if (obj) { \
00409         u_free(u_hmap_o_get_key(obj)); \
00410         u_free(u_hmap_o_get_val(obj)); \
00411         u_hmap_o_free(obj); \
00412         obj = NULL; \
00413     }
00414     
00415     u_dbg("example_dynamic_own_user()");
00416 
00417     u_test_err_if (u_hmap_opts_new(&opts));
00418 
00419     /* hmap owns data by default - change it */
00420     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_OWNSDATA));
00421 
00422     /* no overwrites allowed by default - change this too  */
00423     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_NO_OVERWRITE));
00424 
00425     u_test_err_if (u_hmap_new(opts, &hmap));
00426 
00427     /* insert some sample elements */
00428     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, (void *) u_strdup("EN"), 
00429                     (void *) u_strdup("Hello world!")), &obj));
00430     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, (void *) u_strdup("IT"), 
00431                     (void *) u_strdup("Ciao mondo!")), &obj));
00432     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, (void *) u_strdup("DE"), 
00433                     (void *) u_strdup("Hallo Welt!")), &obj));
00434 
00435     /* retrieve and print values to console */
00436     u_test_err_if (u_hmap_get(hmap, "IT", &obj)); 
00437     u_dbg("hmap['%s'] = %s", (char *) u_hmap_o_get_key(obj), 
00438             (char *) u_hmap_o_get_val(obj));
00439     u_test_err_if (u_hmap_get(hmap, "DE", &obj)); 
00440     u_dbg("hmap['%s'] = %s", (char *) u_hmap_o_get_key(obj), 
00441             (char *) u_hmap_o_get_val(obj));
00442     u_test_err_if (u_hmap_get(hmap, "EN", &obj)); 
00443     u_dbg("hmap['%s'] = %s", (char *) u_hmap_o_get_key(obj), 
00444             (char *) u_hmap_o_get_val(obj));
00445 
00446     /* remove an element and replace it */
00447     u_test_err_if (u_hmap_del(hmap, "DE", &obj)); 
00448     OBJ_FREE(obj);
00449 
00450     /* check that it has been deleted */
00451     u_test_err_if (u_hmap_get(hmap, "DE", &obj) == 0); 
00452 
00453     /* replace with a new element and print it */
00454     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, (void *) u_strdup("DE"), 
00455                     (void *) u_strdup("Auf Wiedersehen!")), NULL));
00456     u_test_err_if (u_hmap_put(hmap, u_hmap_o_new(hmap, (void *) u_strdup("DE"), 
00457                     (void *) u_strdup("Auf Wiedersehen2!")), &obj));
00458     OBJ_FREE(obj);
00459     u_test_err_if (u_hmap_get(hmap, "DE", &obj)); 
00460     u_dbg("hmap['%s'] = %s", (char *) u_hmap_o_get_key(obj), 
00461             (char *) u_hmap_o_get_val(obj));
00462 
00463     u_hmap_del(hmap, "IT", &obj);
00464     OBJ_FREE(obj);
00465     u_hmap_del(hmap, "DE", &obj);
00466     OBJ_FREE(obj);
00467     u_hmap_del(hmap, "EN", &obj);
00468     OBJ_FREE(obj);
00469 
00470     /* free hmap (options and elements are freed automatically) */
00471     u_hmap_free(hmap);
00472     u_hmap_opts_free(opts);
00473 
00474     return U_TEST_SUCCESS;
00475 
00476 err:
00477     U_FREEF(hmap, u_hmap_free);
00478     U_FREEF(opts, u_hmap_opts_free);
00479 
00480     return U_TEST_FAILURE;
00481 }
00482 
00483 static int example_types_custom (u_test_case_t *tc)
00484 {
00485     u_hmap_opts_t *opts = NULL;
00486     u_hmap_t *hmap = NULL;
00487     u_hmap_o_t *obj = NULL; 
00488     int keys[] = { 2, 1, 4, 7, 4, 3, 6, 1, 5 };
00489     const char *vals[] = { "two", "one", "four", "seven", "four2", "three", 
00490         "six", "one2", "five" };
00491     int i;
00492     
00493     u_dbg("example_types_custom()"); 
00494 
00495     u_test_err_if (u_hmap_opts_new(&opts));
00496 
00497     u_test_err_if (u_hmap_opts_set_option(opts, U_HMAP_OPTS_HASH_STRONG));
00498     u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_NO_OVERWRITE));
00499     
00500     u_test_err_if (u_hmap_opts_set_key_type(opts, U_HMAP_OPTS_DATATYPE_OPAQUE));
00501     u_test_err_if (u_hmap_opts_set_key_sz(opts, sizeof(int)));
00502 
00503     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00504 
00505     u_test_err_if (u_hmap_opts_set_size(opts, 3));
00506     u_test_err_if (u_hmap_opts_set_hashfunc(opts, &__sample_hash));
00507     u_test_err_if (u_hmap_opts_set_compfunc(opts, &__sample_comp));
00508     u_test_err_if (u_hmap_opts_set_strfunc(opts, &__sample_str));
00509 
00510     u_test_err_if (u_hmap_new(opts, &hmap));
00511 
00512     for (i = 0; i < 9; i++) {
00513         u_test_err_if ((obj = u_hmap_o_new(hmap, &keys[i], vals[i])) == NULL);
00514         u_test_err_if (u_hmap_put(hmap, obj, NULL));
00515     }
00516 
00517 #ifdef DEBUG_HEAVY
00518     u_hmap_dbg(hmap);
00519 #endif
00520 
00521     for (i = 0; i < 9; i++) {
00522         u_test_err_if (u_hmap_get(hmap, &keys[i], &obj)); 
00523         u_dbg("o: %s, v: %s", u_hmap_o_get_val(obj), vals[i]);
00524     }
00525 
00526     u_hmap_free(hmap);
00527     u_hmap_opts_free(opts);
00528 
00529     return U_TEST_SUCCESS;
00530 err:
00531     U_FREEF(hmap, u_hmap_free);
00532     U_FREEF(opts, u_hmap_opts_free);
00533 
00534     return U_TEST_FAILURE;
00535 }
00536 
00537 static int is_vowel (char c)
00538 {
00539     return (c == 'a' || c == 'A' ||
00540             c == 'e' || c == 'E' ||
00541             c == 'i' || c == 'I' ||
00542             c == 'o' || c == 'o' ||
00543             c == 'u' || c == 'U');
00544 }
00545 
00551 static int __pcy_custom_cmp (void *o1, void *o2)
00552 {
00553     /* cast to original value data type */
00554     const char *s1 = (const char *) o1;
00555     const char *s2 = (const char *) o2;
00556     char c1 = s1[0];
00557     char c2 = s2[0];
00558 
00559     if (is_vowel(c1) == is_vowel(c2))       /* same priority */
00560         return 0;
00561     else if (is_vowel(c1) > is_vowel(c2))   /* c1 has higher priority */
00562         return 1;
00563     else
00564         return -1;                          /* c1 has lower priority */
00565 }
00566 
00575 static int example_policies (u_test_case_t *tc)
00576 {
00577     u_hmap_opts_t *opts = NULL;
00578     u_hmap_t *hmap = NULL;
00579     int i;
00580 
00581     for (i = 0; i <= U_HMAP_PCY_LAST; i++) {
00582 
00583         u_dbg("running policy %d", i);
00584 
00585         u_test_err_if (u_hmap_opts_new(&opts));
00586         u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00587         u_test_err_if (u_hmap_opts_unset_option(opts, U_HMAP_OPTS_NO_OVERWRITE));
00588         u_test_err_if (u_hmap_opts_set_size(opts, 3));
00589         u_test_err_if (u_hmap_opts_set_max(opts, 3));
00590         u_test_err_if (u_hmap_opts_set_policy(opts, i));
00591         if (i == U_HMAP_PCY_CUSTOM)
00592             u_test_err_if (u_hmap_opts_set_policy_cmp(opts, __pcy_custom_cmp));
00593         u_test_err_if (u_hmap_easy_new(opts, &hmap));
00594 
00595         u_test_err_if (u_hmap_easy_put(hmap, "a", (const void *) "A"));
00596         u_test_err_if (u_hmap_easy_put(hmap, "b", (const void *) "B"));
00597         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "b"), "B") != 0);
00598         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "b"), "B") != 0);
00599         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "b"), "B") != 0);
00600         u_test_err_if (u_hmap_easy_put(hmap, "c", (const void *) "C"));
00601 
00602         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "a"), "A") != 0);
00603         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "a"), "A") != 0);
00604         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "a"), "A") != 0);
00605         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "a"), "A") != 0);
00606 
00607         u_dbg("before any discards");
00608         u_hmap_dbg(hmap); u_hmap_pcy_dbg(hmap);
00609 
00610         u_test_err_if (u_hmap_easy_put(hmap, "d", (const void *) "D"));
00611         /* test overwrite of policies */
00612         u_test_err_if (u_hmap_easy_put(hmap, "d", (const void *) "D2"));
00613 
00614         u_dbg("after discard 1");
00615         u_hmap_pcy_dbg(hmap);
00616 
00617         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "d"), "D2") != 0);
00618         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "d"), "D2") != 0);
00619         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "d"), "D2") != 0);
00620         u_test_err_if (strcmp(u_hmap_easy_get(hmap, "d"), "D2") != 0);
00621 
00622         u_dbg("after accesses");
00623         u_hmap_pcy_dbg(hmap);
00624 
00625         u_test_err_if (u_hmap_easy_put(hmap, "e", (const void *) "E"));
00626         u_dbg("after discard 2");
00627 
00628         u_hmap_dbg(hmap); u_hmap_pcy_dbg(hmap);
00629 
00630         U_FREEF(hmap, u_hmap_easy_free);
00631         U_FREEF(opts, u_hmap_opts_free);
00632     }
00633 
00634     return U_TEST_SUCCESS;
00635 err:
00636     U_FREEF(hmap, u_hmap_easy_free);
00637     U_FREEF(opts, u_hmap_opts_free);
00638 
00639     return U_TEST_FAILURE;
00640 }
00641 
00642 static int test_resize (u_test_case_t *tc)
00643 {
00644     enum { NUM_ELEMS = 100000, MAX_STR = 256 };
00645     u_hmap_opts_t *opts = NULL;
00646     u_hmap_t *hmap = NULL;
00647     int i = 0;
00648     char key[MAX_STR], 
00649          val[MAX_STR];
00650 
00651     u_dbg("test_resize()");
00652 
00653     u_test_err_if (u_hmap_opts_new(&opts));
00654 
00655     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00656     u_test_err_if (u_hmap_opts_set_size(opts, 3));
00657 
00658     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00659 
00660     for (i = 0; i < NUM_ELEMS; ++i) {
00661         u_snprintf(key, MAX_STR, "key%d", i);
00662         u_snprintf(val, MAX_STR, "val%d", i);
00663         u_test_err_if (u_hmap_easy_put(hmap, key, val));
00664     }
00665 
00666     for (i = 0; i < NUM_ELEMS; ++i) {
00667         u_snprintf(key, MAX_STR, "key%d", i);
00668         u_test_err_if (u_hmap_easy_del(hmap, key)); 
00669     }
00670 
00671     u_hmap_easy_free(hmap);
00672     u_hmap_opts_free(opts);
00673     
00674     return U_TEST_SUCCESS;
00675 
00676 err:
00677     U_FREEF(hmap, u_hmap_easy_free);
00678     U_FREEF(opts, u_hmap_opts_free);
00679 
00680     return U_TEST_FAILURE;
00681 }
00682 
00683 static int test_linear (u_test_case_t *tc)
00684 {
00685     enum { NUM_ELEMS = 100000, MAX_STR = 256 };
00686     u_hmap_opts_t *opts = NULL;
00687     u_hmap_t *hmap = NULL;
00688     int i = 0;
00689     char key[MAX_STR], 
00690          val[MAX_STR];
00691 
00692     u_dbg("test_linear()");
00693 
00694     u_test_err_if (u_hmap_opts_new(&opts));
00695 
00696     u_test_err_if (u_hmap_opts_set_val_type(opts, U_HMAP_OPTS_DATATYPE_STRING));
00697     u_test_err_if (u_hmap_opts_set_size(opts, 1000));
00698     u_test_err_if (u_hmap_opts_set_type(opts, U_HMAP_TYPE_LINEAR));
00699 
00700     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00701 
00702     for (i = 0; i < NUM_ELEMS; ++i) {
00703         u_snprintf(key, MAX_STR, "key%d", i);
00704         u_snprintf(val, MAX_STR, "val%d", i);
00705         u_test_err_if (u_hmap_easy_put(hmap, key, val));
00706     }
00707 
00708     for (i = 0; i < NUM_ELEMS; ++i) {
00709         u_snprintf(key, MAX_STR, "key%d", i);
00710         u_test_err_if (u_hmap_easy_del(hmap, key)); 
00711     }
00712 
00713     u_hmap_easy_free(hmap);
00714     u_hmap_opts_free(opts);
00715     
00716     return U_TEST_SUCCESS;
00717 
00718 err:
00719     U_FREEF(hmap, u_hmap_easy_free);
00720     U_FREEF(opts, u_hmap_opts_free);
00721 
00722     return U_TEST_FAILURE;
00723 }
00724 
00729 static int test_scope (u_test_case_t *tc)
00730 {
00731     enum { KEY_SZ = 256 };
00732     int i;
00733     u_hmap_opts_t *opts = NULL;
00734     u_hmap_t *hmap = NULL;
00735     const char *vals[] = { "zero", "one", "two", "three", "four", "five", 
00736         "six", "seven", "eight", "nine" };
00737     char key[KEY_SZ];
00738 
00739     u_dbg("test_scope()");
00740 
00741     u_test_err_if (u_hmap_opts_new(&opts));
00742 
00743     /* static data - no free function required */
00744     u_test_err_if (u_hmap_opts_set_val_freefunc(opts, NULL));
00745 
00746     /* default is string key and pointer value */
00747     u_test_err_if (u_hmap_easy_new(opts, &hmap));
00748 
00749     for (i = 0; i < 10; i++) {
00750         u_snprintf(key, KEY_SZ, "key%d", i);
00751         u_test_err_if (u_hmap_easy_put(hmap, key, vals[i]));
00752     }
00753 
00754 #ifdef DEBUG_HEAVY
00755     u_hmap_dbg(hmap);
00756 #endif
00757 
00758     for (i = 0; i < 10; i++) {
00759         u_snprintf(key, KEY_SZ, "key%d", i);
00760         u_test_err_if (strcmp(u_hmap_easy_get(hmap, key), vals[i]) != 0);
00761     }
00762 
00763     u_hmap_easy_free(hmap);
00764     u_hmap_opts_free(opts);
00765 
00766     return U_TEST_SUCCESS;
00767 err:
00768     U_FREEF(hmap, u_hmap_easy_free);
00769     U_FREEF(opts, u_hmap_opts_free);
00770 
00771     return U_TEST_FAILURE;
00772 }
00773 
00774 int test_suite_hmap_register (u_test_t *t)
00775 {
00776     u_test_suite_t *ts = NULL;
00777 
00778     con_err_if (u_test_suite_new("Hash Map", &ts));
00779 
00780     /* examples */
00781     con_err_if (u_test_case_register("Static Example", 
00782                 example_static, ts));
00783     con_err_if (u_test_case_register("Basic (hmap_easy interface)",
00784                 example_easy_basic, ts));
00785     con_err_if (u_test_case_register("Static (hmap_easy interface)", 
00786                 example_easy_static, ts));
00787     con_err_if (u_test_case_register("Dynamic (hmap_easy interface)",
00788                 example_easy_dynamic, ts));
00789     con_err_if (u_test_case_register("Opaque (hmap_easy interface)", 
00790                 example_easy_opaque, ts));
00791     con_err_if (u_test_case_register("Dynamic, Hmap Owns",
00792                 example_dynamic_own_hmap, ts));
00793     con_err_if (u_test_case_register("Dynamic, User Owns",
00794                 example_dynamic_own_user, ts));
00795     con_err_if (u_test_case_register("Custom Handlers",
00796                 example_types_custom, ts));
00797     con_err_if (u_test_case_register("Discard Policies",
00798                 example_policies, ts));
00799 
00800     /* tests */
00801     con_err_if (u_test_case_register("Resize", test_resize, ts));
00802     con_err_if (u_test_case_register("Linear Probing", test_linear, ts));
00803     con_err_if (u_test_case_register("Scoping", test_scope, ts));
00804 
00805     /* hmap depends on the strings module */
00806     con_err_if (u_test_suite_dep_register("Strings", ts));
00807 
00808     return u_test_suite_add(ts, t);
00809 err:
00810     u_test_suite_free(ts);
00811     return ~0;
00812 }

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