Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Change parameter names from 'head' to 'dict'. Add two functions: xbt_dict_reset(...
authorthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 4 Aug 2006 14:42:20 +0000 (14:42 +0000)
committerthiery <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 4 Aug 2006 14:42:20 +0000 (14:42 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2693 48e7efb5-ca39-0410-a469-dd3cf9ba447f

include/xbt/dict.h
src/xbt/dict.c
src/xbt/dict_private.h

index 017d985..a25f957 100644 (file)
@@ -58,12 +58,14 @@ SG_BEGIN_DECL()
  *  @{
  */
 
-  void  xbt_dict_set(xbt_dict_t head, const char *key, void *data, void_f_pvoid_t *free_ctn);
-  void *xbt_dict_get(xbt_dict_t head,const char *key);
+  void  xbt_dict_set(xbt_dict_t dict, const char *key, void *data, void_f_pvoid_t *free_ctn);
+  void *xbt_dict_get(xbt_dict_t dict,const char *key);
   void *xbt_dict_get_or_null(xbt_dict_t dict, const char *key);
 
-  void xbt_dict_remove(xbt_dict_t head, const char *key);
-  void xbt_dict_dump(xbt_dict_t head,void (*output)(void*));
+  void xbt_dict_remove(xbt_dict_t dict, const char *key);
+  void xbt_dict_reset(xbt_dict_t dict);
+  int xbt_dict_length(xbt_dict_t dict);
+  void xbt_dict_dump(xbt_dict_t dict, void (*output)(void*));
   
 /** @} */
 /** @defgroup XBT_dict_nnul Dictionnaries with non-nul terminated keys
@@ -73,12 +75,12 @@ SG_BEGIN_DECL()
  *
  *  @{
  */
-  void  xbt_dict_set_ext(xbt_dict_t     head,
+  void  xbt_dict_set_ext(xbt_dict_t     dict,
                         const char     *key, int  key_len,
                         void           *data,
                         void_f_pvoid_t *free_ctn);
-  void *xbt_dict_get_ext(xbt_dict_t head,const char *key, int key_len);
-  void xbt_dict_remove_ext(xbt_dict_t head, const char *key, int key_len);
+  void *xbt_dict_get_ext(xbt_dict_t dict, const char *key, int key_len);
+  void xbt_dict_remove_ext(xbt_dict_t dict, const char *key, int key_len);
 
 
 /** @} */
@@ -94,7 +96,7 @@ SG_BEGIN_DECL()
 \verbatim xbt_dict_cursor_t cursor=NULL;
  char *key,*data;
 
- xbt_dict_foreach(head,cursor,key,data) {
+ xbt_dict_foreach(dict,cursor,key,data) {
     printf("   - Seen:  %s->%s\n",key,data);
  }\endverbatim
 
@@ -105,7 +107,7 @@ SG_BEGIN_DECL()
 
   /** @brief Cursor on dictionnaries (opaque type) */
   typedef struct xbt_dict_cursor_ *xbt_dict_cursor_t;
-  xbt_dict_cursor_t xbt_dict_cursor_new(const xbt_dict_t head);
+  xbt_dict_cursor_t xbt_dict_cursor_new(const xbt_dict_t dict);
   void               xbt_dict_cursor_free(xbt_dict_cursor_t *cursor);
 
   void xbt_dict_cursor_rewind(xbt_dict_cursor_t cursor);
index 3561e8a..c28171f 100644 (file)
@@ -44,6 +44,7 @@ xbt_dict_t xbt_dict_new_ext(int hashsize) {
   for (i = 0; i < hashsize; i++) {
     dict->table[i] = NULL;
   }
+  dict->count = 0;
 
   return dict;
 }
@@ -154,6 +155,7 @@ void xbt_dict_set_ext(xbt_dict_t      dict,
     else {
       previous->next = current;
     }
+    dict->count++;
   }
   else {
     /* there is already an element with the same key: we overwrite it */
@@ -168,7 +170,7 @@ void xbt_dict_set_ext(xbt_dict_t      dict,
 /**
  * \brief Add data to the dict (null-terminated key)
  *
- * \param dict the head of the dict
+ * \param dict the dict
  * \param key the key to set the new data
  * \param data the data to add in the dict
  * \param free_ctn function to call with (\a key as argument) when 
@@ -233,7 +235,19 @@ void *xbt_dict_get(xbt_dict_t dict,
                   const char *key) {
   xbt_assert(dict);
 
-  return xbt_dict_get_ext(dict, key, strlen(key));
+  unsigned int hash_code = xbt_dict_hash(key) % dict->table_size;
+  xbt_dictelm_t current;
+
+  current = dict->table[hash_code];
+  while (current != NULL && (strcmp(key, current->key))) {
+    current = current->next;
+  }
+
+  if (current == NULL) {
+    THROW1(not_found_error, 0, "key %s not found", key);
+  }
+
+  return current->content;
 }
 
 /**
@@ -292,12 +306,13 @@ void xbt_dict_remove_ext(xbt_dict_t  dict,
   }
 
   xbt_dictelm_free(current);
+  dict->count--;
 }
 
 /**
  * \brief Remove data from the dict (null-terminated key)
  *
- * \param dict the head of the dict
+ * \param dict the dict
  * \param key the key of the data to be removed
  *
  * Remove the entry associated with the given \a key
@@ -309,6 +324,38 @@ void xbt_dict_remove(xbt_dict_t  dict,
   xbt_dict_remove_ext(dict, key, strlen(key));
 }
 
+/**
+ * \brief Remove all data from the dict
+ * \param dict the dict
+ */
+void xbt_dict_reset(xbt_dict_t dict) {
+  xbt_assert(dict);
+
+  int i;
+  xbt_dictelm_t current, previous = NULL;
+  for (i = 0; i < dict->table_size; i++) {
+    current = dict->table[i];
+    while (current != NULL) {
+      previous = current;
+      current = current->next;
+      xbt_dictelm_free(previous);
+    }
+    dict->table[i] = NULL;
+  }
+
+  dict->count = 0;
+}
+
+/**
+ * \brief Return the number of elements in the dict.
+ * \param dict a dictionary
+ */
+int xbt_dict_length(xbt_dict_t dict) {
+  xbt_assert(dict);
+
+  return dict->count;
+}
+
 /*
  * Add an already mallocated element to a dictionary.
  */
@@ -437,6 +484,11 @@ static void search_not_found(xbt_dict_t head, const char *data) {
   }
 }
 
+static void count(xbt_dict_t dict, int length) {
+  xbt_test_add1("Count elements (expecting %d)", length);
+  xbt_test_assert2(xbt_dict_length(dict) == length, "Length(%d) != %d.", xbt_dict_length(dict), length);
+}
+
 xbt_ex_t e;
 xbt_dict_t head=NULL;
 char *data;
@@ -448,6 +500,7 @@ XBT_TEST_UNIT("basic",test_dict_basic,"Basic usage: change, retrieve, traverse")
 
   xbt_test_add0("Traverse the full dictionnary");
   fill(&head);
+  count(head, 7);
 
   search(head,"12a");
   traverse(head);
@@ -458,17 +511,22 @@ XBT_TEST_UNIT("basic",test_dict_basic,"Basic usage: change, retrieve, traverse")
 
   /* CHANGING */
   fill(&head);
+  count(head, 7);
   xbt_test_add0("Change 123 to 'Changed 123'");
   xbt_dict_set(head,"123",strdup("Changed 123"),&free);
+  count(head, 7);
 
   xbt_test_add0("Change 123 back to '123'");
   xbt_dict_set(head,"123",strdup("123"),&free);
+  count(head, 7);
 
   xbt_test_add0("Change 12a to 'Dummy 12a'");
   xbt_dict_set(head,"12a",strdup("Dummy 12a"),&free);
+  count(head, 7);
 
   xbt_test_add0("Change 12a to '12a'");
   xbt_dict_set(head,"12a",strdup("12a"),&free);
+  count(head, 7);
 
   xbt_test_add0("Traverse the resulting dictionnary");
   traverse(head);
@@ -505,6 +563,7 @@ XBT_TEST_UNIT("basic",test_dict_basic,"Basic usage: change, retrieve, traverse")
 
 XBT_TEST_UNIT("remove",test_dict_remove,"Removing some values"){
   fill(&head);
+  count(head, 7);
   xbt_test_add0("Remove non existing data");
   TRY {
     debuged_remove(head,"Does not exist");
@@ -520,9 +579,13 @@ XBT_TEST_UNIT("remove",test_dict_remove,"Removing some values"){
   xbt_test_add0("Remove each data manually (traversing the resulting dictionnary each time)");
   fill(&head);
   debuged_remove(head,"12a");    traverse(head);
+  count(head, 6);
   debuged_remove(head,"12b");    traverse(head);
+  count(head, 5);
   debuged_remove(head,"12");     traverse(head);
+  count(head, 4);
   debuged_remove(head,"123456"); traverse(head);
+  count(head, 3);
   TRY {
     debuged_remove(head,"12346");
   } CATCH(e) {
@@ -542,6 +605,13 @@ XBT_TEST_UNIT("remove",test_dict_remove,"Removing some values"){
     xbt_ex_free(e);
   }                              traverse(head);
   
+  xbt_test_add0("Remove all values");
+  xbt_dict_free(&head);
+  fill(&head);
+  xbt_dict_reset(head);
+  count(head, 0);
+  traverse(head);
+
   xbt_test_add0("Free the dictionnary twice");
   xbt_dict_free(&head);
   xbt_dict_free(&head);      
index 97b23c9..2aae858 100644 (file)
@@ -30,6 +30,7 @@ typedef struct xbt_dictelm_ {
 typedef struct xbt_dict_ {
   xbt_dictelm_t *table;
   int table_size;
+  int count;
 } s_xbt_dict_t;
 
 typedef struct xbt_dict_cursor_ s_xbt_dict_cursor_t;