X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/25d6952dcf52e6ffc1e4a402af0e2d3c17ac3935..169edc40a9d6aac50da8647a98df1e2b7cd92727:/src/xbt/dict.c?ds=sidebyside diff --git a/src/xbt/dict.c b/src/xbt/dict.c index 37bc17511d..8810081a5f 100644 --- a/src/xbt/dict.c +++ b/src/xbt/dict.c @@ -10,7 +10,7 @@ #include "xbt/ex.h" #include "dict_private.h" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(dict,xbt, +XBT_LOG_NEW_SUBCATEGORY(xbt_dict,xbt, "Dictionaries provide the same functionnalities than hash tables"); /*####[ Private prototypes ]#################################################*/ @@ -140,7 +140,7 @@ void * xbt_dict_get_or_null(xbt_dict_t dict, const char *key) { xbt_ex_t e; - void *res; + void *res=NULL; TRY { res = xbt_dictelm_get(dict->head, key); } CATCH(e) { @@ -207,3 +207,402 @@ xbt_dict_dump(xbt_dict_t dict, printf("Dict %p:\n", (void*)dict); xbt_dictelm_dump(dict ? dict->head: NULL, output); } + +#ifdef SIMGRID_TEST +#include "xbt.h" +#include "xbt/ex.h" +#include "portable.h" + +XBT_LOG_EXTERNAL_CATEGORY(xbt_dict); +XBT_LOG_DEFAULT_CATEGORY(xbt_dict); + +XBT_TEST_SUITE("dict","Dict data container"); + +static void print_str(void *str) { + printf("%s",(char*)PRINTF_STR(str)); +} + +static void debuged_add(xbt_dict_t head,const char*key) +{ + char *data=xbt_strdup(key); + + xbt_test_log1("Add %s",PRINTF_STR(key)); + + xbt_dict_set(head,key,data,&free); + if (XBT_LOG_ISENABLED(xbt_dict,xbt_log_priority_debug)) { + xbt_dict_dump(head,(void (*)(void*))&printf); + fflush(stdout); + } +} + +static void fill(xbt_dict_t *head) { + xbt_test_add0("Fill in the dictionnary"); + + *head = xbt_dict_new(); + debuged_add(*head,"12"); + debuged_add(*head,"12a"); + debuged_add(*head,"12b"); + debuged_add(*head,"123"); + debuged_add(*head,"123456"); + /* Child becomes child of what to add */ + debuged_add(*head,"1234"); + /* Need of common ancestor */ + debuged_add(*head,"123457"); + +} + +static void search(xbt_dict_t head,const char*key) { + void *data; + + xbt_test_add1("Search %s",key); + data=xbt_dict_get(head,key); + xbt_test_log1("Found %s",(char *)data); + if (data) + xbt_test_assert0(!strcmp((char*)data,key),"Key and data do not match"); +} + +static void debuged_remove(xbt_dict_t head,const char*key) { + + xbt_test_add1("Remove '%s'",PRINTF_STR(key)); + xbt_dict_remove(head,key); + /* xbt_dict_dump(head,(void (*)(void*))&printf); */ +} + + +static void traverse(xbt_dict_t head) { + xbt_dict_cursor_t cursor=NULL; + char *key; + char *data; + + xbt_dict_foreach(head,cursor,key,data) { + xbt_test_log2("Seen: %s->%s",PRINTF_STR(key),PRINTF_STR(data)); + xbt_test_assert2(!data || !strcmp(key,data), + "Key(%s) != value(%s). Abording\n",key,data); + } +} + +static void search_not_found(xbt_dict_t head, const char *data) { + xbt_ex_t e; + + xbt_test_add1("Search %s (expected not to be found)",data); + + TRY { + data = xbt_dict_get(head,"Can't be found"); + THROW1(unknown_error,0,"Found something which shouldn't be there (%s)",data); + } CATCH(e) { + if (e.category != not_found_error) + xbt_test_exception(e); + xbt_ex_free(e); + } +} + +xbt_ex_t e; +xbt_dict_t head=NULL; +char *data; + + +XBT_TEST_UNIT("basic",test_dict_basic,"Basic usage: change, retrieve, traverse"){ + + xbt_test_add0("Traversal the empty dictionnary"); + traverse(head); + + xbt_test_add0("Traverse the full dictionnary"); + fill(&head); + + search(head,"12a"); + traverse(head); + + xbt_test_add0("Free the dictionnary (twice)"); + xbt_dict_free(&head); + xbt_dict_free(&head); + + /* CHANGING */ + fill(&head); + xbt_test_add0("Change 123 to 'Changed 123'"); + xbt_dict_set(head,"123",strdup("Changed 123"),&free); + + xbt_test_add0("Change 123 back to '123'"); + xbt_dict_set(head,"123",strdup("123"),&free); + + xbt_test_add0("Change 12a to 'Dummy 12a'"); + xbt_dict_set(head,"12a",strdup("Dummy 12a"),&free); + + xbt_test_add0("Change 12a to '12a'"); + xbt_dict_set(head,"12a",strdup("12a"),&free); + + xbt_test_add0("Traverse the resulting dictionnary"); + traverse(head); + + /* RETRIEVE */ + xbt_test_add0("Search 123"); + data = xbt_dict_get(head,"123"); + xbt_test_assert(data); + xbt_test_assert(!strcmp("123",data)); + + search_not_found(head,"Can't be found"); + search_not_found(head,"123 Can't be found"); + search_not_found(head,"12345678 NOT"); + + search(head,"12a"); + search(head,"12b"); + search(head,"12"); + search(head,"123456"); + search(head,"1234"); + search(head,"123457"); + + xbt_test_add0("Traverse the resulting dictionnary"); + traverse(head); + + /* xbt_dict_dump(head,(void (*)(void*))&printf); */ + + xbt_test_add0("Free the dictionnary twice"); + xbt_dict_free(&head); + xbt_dict_free(&head); + + xbt_test_add0("Traverse the resulting dictionnary"); + traverse(head); +} + +XBT_TEST_UNIT("remove",test_dict_remove,"Removing some values"){ + fill(&head); + xbt_test_add0("Remove non existing data"); + TRY { + debuged_remove(head,"Does not exist"); + } CATCH(e) { + if (e.category != not_found_error) + xbt_test_exception(e); + xbt_ex_free(e); + } + traverse(head); + + xbt_dict_free(&head); + + xbt_test_add0("Remove data from the NULL dict"); + TRY { + debuged_remove(head,"12345"); + } CATCH(e) { + if (e.category != arg_error) + xbt_test_exception(e); + xbt_ex_free(e); + } + + xbt_test_add0("Remove each data manually (traversing the resulting dictionnary each time)"); + fill(&head); + debuged_remove(head,"12a"); traverse(head); + debuged_remove(head,"12b"); traverse(head); + debuged_remove(head,"12"); traverse(head); + debuged_remove(head,"123456"); traverse(head); + TRY { + debuged_remove(head,"12346"); + } CATCH(e) { + if (e.category != not_found_error) + xbt_test_exception(e); + xbt_ex_free(e); + traverse(head); + } + debuged_remove(head,"1234"); traverse(head); + debuged_remove(head,"123457"); traverse(head); + debuged_remove(head,"123"); traverse(head); + TRY { + debuged_remove(head,"12346"); + } CATCH(e) { + if (e.category != not_found_error) + xbt_test_exception(e); + xbt_ex_free(e); + } traverse(head); + + xbt_test_add0("Free the dictionnary twice"); + xbt_dict_free(&head); + xbt_dict_free(&head); +} + +XBT_TEST_UNIT("nulldata",test_dict_nulldata,"NULL data management"){ + fill(&head); + + xbt_test_add0("Store NULL under 'null'"); + xbt_dict_set(head,"null",NULL,NULL); + search(head,"null"); + + xbt_test_add0("Check whether I see it while traversing..."); + { + xbt_dict_cursor_t cursor=NULL; + char *key; + int found=0; + + xbt_dict_foreach(head,cursor,key,data) { + xbt_test_log2("Seen: %s->%s",PRINTF_STR(key),PRINTF_STR(data)); + if (!strcmp(key,"null")) + found = 1; + } + xbt_test_assert0(found,"the key 'null', associated to NULL is not found"); + } + xbt_dict_free(&head); +} + +#define NB_ELM 20000 +#define SIZEOFKEY 1024 +static int countelems(xbt_dict_t head) { + xbt_dict_cursor_t cursor; + char *key; + void *data; + int res = 0; + + xbt_dict_foreach(head,cursor,key,data) { + res++; + } + return res; +} + +XBT_TEST_UNIT("crash",test_dict_crash,"Crash test"){ + xbt_dict_t head=NULL; + int i,j,k, nb; + char *key; + void *data; + + srand((unsigned int)time(NULL)); + + xbt_test_add0("CRASH test"); + xbt_test_log0("Fill the struct, count its elems and frees the structure (x10)"); + xbt_test_log1("using 1000 elements with %d chars long randomized keys.",SIZEOFKEY); + + for (i=0;i<10;i++) { + head=xbt_dict_new(); + // if (i%10) printf("."); else printf("%d",i/10); fflush(stdout); + nb=0; + for (j=0;j<1000;j++) { + key=xbt_malloc(SIZEOFKEY); + + for (k=0;k0) + printf("Test %d\n",i); + /* else if (i%10) printf("."); else printf("%d",i/10);*/ + + for (j=0;j0) printf (" Add {"); + + for (l=0 ; l0) printf("%p=%s %s ",key, key,(l0) printf("in multitree %p.\n",mdict); + + xbt_multidict_set(mdict,keys,xbt_strdup(key),free); + + data = xbt_multidict_get(mdict,keys); + + xbt_test_assert2(data && !strcmp((char*)data,key), + "Retrieved value (%s) does not match the entrered one (%s)\n", + (char*)data,key); + } + xbt_dict_free(&mdict); + } + + xbt_dynar_free(&keys); + +/* if (verbose>0) + xbt_dict_dump(mdict,&xbt_dict_print);*/ + + xbt_dict_free(&mdict); + xbt_dynar_free(&keys); + +} +#endif /* SIMGRID_TEST */