Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix a 3 years old bug in the dictionary's function xbt_dict_get_or_null().
[simgrid.git] / src / xbt / dict.c
index 21b8f60..708cffb 100644 (file)
@@ -1,6 +1,7 @@
 /* dict - a generic dictionary, variation over hash table                   */
 
-/* Copyright (c) 2003-2010 Martin Quinson. All rights reserved.             */
+/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -39,18 +40,6 @@ xbt_dict_t xbt_dict_new(void)
 {
   xbt_dict_t dict;
 
-  if (dict_mallocator == NULL) {
-    /* first run */
-    dict_mallocator = xbt_mallocator_new(256,
-                                         dict_mallocator_new_f,
-                                         dict_mallocator_free_f,
-                                         dict_mallocator_reset_f);
-    dict_elm_mallocator = xbt_mallocator_new(256,
-                                             dict_elm_mallocator_new_f,
-                                             dict_elm_mallocator_free_f,
-                                             dict_elm_mallocator_reset_f);
-  }
-
   dict = xbt_mallocator_get(dict_mallocator);
   dict->table_size = 127;
   dict->table = xbt_new0(xbt_dictelm_t, dict->table_size + 1);
@@ -100,7 +89,7 @@ void xbt_dict_free(xbt_dict_t * dict)
  */
 XBT_INLINE unsigned int xbt_dict_size(xbt_dict_t dict)
 {
-  return dict->count;
+  return (dict ? (unsigned int) dict->count : (unsigned int) 0);
 }
 
 /**
@@ -422,7 +411,7 @@ XBT_INLINE void *xbt_dict_get_or_null(xbt_dict_t dict, const char *key)
 
   current = dict->table[hash_code & dict->table_size];
   while (current != NULL &&
-         hash_code != current->hash_code && strcmp(key, current->key))
+         (hash_code != current->hash_code || strcmp(key, current->key)))
     current = current->next;
 
   if (current == NULL)
@@ -648,7 +637,13 @@ void xbt_dict_dump_output_string(void *s)
 {
   fputs(s, stdout);
 }
-
+/**
+ * \brief test if the dict is empty or not
+ */
+XBT_INLINE int xbt_dict_is_empty(xbt_dict_t dict)
+{
+       return (xbt_dict_size(dict) == 0);
+}
 
 /**
  * \brief Outputs the content of the structure (debugging purpose)
@@ -746,11 +741,33 @@ void xbt_dict_dump_sizes(xbt_dict_t dict)
   xbt_dynar_free(&sizes);
 }
 
+/**
+ * Create the dict mallocators.
+ * This is an internal XBT function called during the lib initialization.
+ * It can be used several times to recreate the mallocator, for example when you switch to MC mode
+ */
+void xbt_dict_preinit(void) {
+  if (dict_mallocator != NULL) {
+    /* Already created. I guess we want to switch to MC mode, so kill the previously created mallocator */
+    xbt_mallocator_free(dict_mallocator);
+    xbt_mallocator_free(dict_elm_mallocator);
+  }
+
+  dict_mallocator = xbt_mallocator_new(256,
+      dict_mallocator_new_f,
+      dict_mallocator_free_f,
+      dict_mallocator_reset_f);
+  dict_elm_mallocator = xbt_mallocator_new(256,
+      dict_elm_mallocator_new_f,
+      dict_elm_mallocator_free_f,
+      dict_elm_mallocator_reset_f);
+}
+
 /**
  * Destroy the dict mallocators.
- * This is an internal XBT function called by xbt_exit().
+ * This is an internal XBT function during the lib initialization
  */
-void xbt_dict_exit(void)
+void xbt_dict_postexit(void)
 {
   if (dict_mallocator != NULL) {
     xbt_mallocator_free(dict_mallocator);
@@ -1150,6 +1167,7 @@ XBT_TEST_UNIT("nulldata", test_dict_nulldata, "NULL data management")
 }
 
 static void debuged_addi(xbt_dict_t head, uintptr_t key, uintptr_t data) {
+       uintptr_t stored_data = 0;
   xbt_test_log2("Add %zu under %zu", data, key);
 
   xbt_dicti_set(head, key, data);
@@ -1157,7 +1175,7 @@ static void debuged_addi(xbt_dict_t head, uintptr_t key, uintptr_t data) {
     xbt_dict_dump(head, (void (*)(void *)) &printf);
     fflush(stdout);
   }
-  uintptr_t stored_data = xbt_dicti_get(head, key);
+  stored_data = xbt_dicti_get(head, key);
   xbt_test_assert3(stored_data==data,
       "Retrieved data (%zu) is not what I just stored (%zu) under key %zu",stored_data,data,key);
 }