[SSSD] [PATCH] dhash: Allow hash_enter() to update entries

Sumit Bose sbose at redhat.com
Wed Sep 29 10:39:40 UTC 2010


Hi,

Patch 0003 add update capabilities to hash_enter(). The current
behaviour was to keep the old entry and return HASH_SUCCESS. I have
added an update test to the unit test. Maybe it make sense to update the
version number to make it easier to detect if updates are possible or
not.

Patch 0001 adds a missing include file and 0002 makes hash_example pass
valgrind without errors.

bye,
Sumit
-------------- next part --------------
From 56add86543006afc497d5a05368549a1293bf5c0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 28 Sep 2010 17:24:57 +0200
Subject: [PATCH 1/3] dhash: add stddef.h to dhash.h

size_t is used in dhash.h and was currently not defined by any included
header file.
---
 dhash/dhash.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/dhash/dhash.h b/dhash/dhash.h
index 70d083e..95f9fff 100644
--- a/dhash/dhash.h
+++ b/dhash/dhash.h
@@ -77,6 +77,7 @@ terms of this license.
 /*****************************************************************************/
 
 #include <stdbool.h>
+#include <stddef.h>
 
 /*****************************************************************************/
 /*********************************** Defines *********************************/
-- 
1.7.2.3

-------------- next part --------------
From 2d52f0e2c9ec84bb9cfbf21d31f0496752d94d4d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 29 Sep 2010 10:05:30 +0200
Subject: [PATCH 2/3] dhash: Fix memory leak in example

---
 dhash/examples/dhash_example.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/dhash/examples/dhash_example.c b/dhash/examples/dhash_example.c
index bd0ca8e..c7eac3d 100644
--- a/dhash/examples/dhash_example.c
+++ b/dhash/examples/dhash_example.c
@@ -81,6 +81,7 @@ int main(int argc, char **argv)
         fprintf(stderr, "cannot add to table \"%s\" (%s)\n", key.str, hash_error_string(error));
         return error;
     }
+    free(key.str);
 
     /* Get a list of keys and print them out, free the list when we're done */
     if ((error = hash_keys(table, &count, &keys)) != HASH_SUCCESS) {
@@ -98,6 +99,7 @@ int main(int argc, char **argv)
     if ((error = hash_lookup(table, &key, &value)) != HASH_SUCCESS) {
         fprintf(stderr, "cannot find key \"%s\" (%s)\n", key.str, hash_error_string(error));
     }
+    free(key.str);
 
     /* Visit each entry in the table, callback will increment count on each visit */
     printf("Iterate using callback\n");
@@ -130,6 +132,7 @@ int main(int argc, char **argv)
 
     /* Assure key is no longer in table */
     assert (!hash_has_key(table, &key));
+    free(key.str);
 
     /* Free the table */
     hash_destroy(table);
-- 
1.7.2.3

-------------- next part --------------
From 8aa865870f6c5892118765073a39062f114412cd Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 29 Sep 2010 12:24:19 +0200
Subject: [PATCH 3/3] dhash: Allow hash_enter() to update entries

---
 dhash/dhash.c               |   61 ++++++++++++++++++++++------------------
 dhash/examples/dhash_test.c |   65 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 27 deletions(-)

diff --git a/dhash/dhash.c b/dhash/dhash.c
index cb292b7..f92e463 100644
--- a/dhash/dhash.c
+++ b/dhash/dhash.c
@@ -898,34 +898,10 @@ int hash_enter(hash_table_t *table, hash_key_t *key, hash_value_t *value)
             memcpy((void *)element->entry.key.str, key->str, len);
             break;
         }
-        switch(element->entry.value.type = value->type) {
-        case HASH_VALUE_UNDEF:
-            element->entry.value.ul = 0;
-            break;
-        case HASH_VALUE_PTR:
-            element->entry.value.ptr = value->ptr;
-            break;
-        case HASH_VALUE_INT:
-            element->entry.value.i = value->i;
-            break;
-        case HASH_VALUE_UINT:
-            element->entry.value.ui = value->ui;
-            break;
-        case HASH_VALUE_LONG:
-            element->entry.value.l = value->l;
-            break;
-        case HASH_VALUE_ULONG:
-            element->entry.value.ul = value->ul;
-            break;
-        case HASH_VALUE_FLOAT:
-            element->entry.value.f = value->f;
-            break;
-        case HASH_VALUE_DOUBLE:
-            element->entry.value.d = value->d;
-            break;
-        }
+
         *chain = element;             /* link into chain */
         element->next = NULL;
+
         /*
          * Table over-full?
          */
@@ -934,7 +910,38 @@ int hash_enter(hash_table_t *table, hash_key_t *key, hash_value_t *value)
                 return error;
             }
         }
-    }                                       /* end not found */
+
+    } else {
+        hdelete_callback(table, HASH_ENTRY_DESTROY, &element->entry);
+    }
+
+    switch(element->entry.value.type = value->type) {
+    case HASH_VALUE_UNDEF:
+        element->entry.value.ul = 0;
+        break;
+    case HASH_VALUE_PTR:
+        element->entry.value.ptr = value->ptr;
+        break;
+    case HASH_VALUE_INT:
+        element->entry.value.i = value->i;
+        break;
+    case HASH_VALUE_UINT:
+        element->entry.value.ui = value->ui;
+        break;
+    case HASH_VALUE_LONG:
+        element->entry.value.l = value->l;
+        break;
+    case HASH_VALUE_ULONG:
+        element->entry.value.ul = value->ul;
+        break;
+    case HASH_VALUE_FLOAT:
+        element->entry.value.f = value->f;
+        break;
+    case HASH_VALUE_DOUBLE:
+        element->entry.value.d = value->d;
+        break;
+    }
+
     return HASH_SUCCESS;
 }
 
diff --git a/dhash/examples/dhash_test.c b/dhash/examples/dhash_test.c
index e5b922d..6c02de1 100644
--- a/dhash/examples/dhash_test.c
+++ b/dhash/examples/dhash_test.c
@@ -135,6 +135,8 @@ int main(int argc, char **argv)
     long i, k;
     int status;
     hash_value_t value;
+    hash_value_t old_value;
+    hash_value_t new_value;
     hash_key_t key;
     char buf[1024];
     hash_table_t *table = NULL;
@@ -404,6 +406,69 @@ int main(int argc, char **argv)
         }
     }
 
+    /* Update an entry */
+    if (test[0].val & 1) {
+        key.type = HASH_KEY_STRING;
+        key.str = test[0].str;
+    } else {
+        key.type = HASH_KEY_ULONG;
+        key.ul = test[0].val;
+    }
+
+    if ((status = hash_lookup(table, &key, &value)) != HASH_SUCCESS) {
+        fprintf(stderr, "Error: failed lookup for value %ld, at line %d (%s)\n",
+                test[0].val,  __LINE__, error_string(status));
+        exit(1);
+    }
+
+    old_value.type = value.type;
+    switch (value.type) {
+        case HASH_VALUE_LONG:
+            old_value.ul = value.ul;
+            break;
+        case HASH_VALUE_PTR:
+            old_value.ptr = strdup(value.ptr);
+            break;
+        default:
+            fprintf(stderr, "Error: unsupported value type for update.\n");
+            exit(1);
+    }
+
+    value.type = HASH_VALUE_PTR;
+    value.ptr = (void *) strdup("Updated");
+
+    if ((status = hash_enter(table, &key, &value)) != HASH_SUCCESS) {
+        fprintf(stderr, "Error: %ld failed insertion at line %d (%s) \n",
+                test[0].val, __LINE__, error_string(status));
+        exit(1);
+    }
+
+    if ((status = hash_lookup(table, &key, &new_value)) != HASH_SUCCESS) {
+        fprintf(stderr, "Error: failed lookup for value %ld, at line %d (%s)\n",
+                test[0].val,  __LINE__, error_string(status));
+        exit(1);
+    }
+
+    if (value.type == new_value.type) {
+        if (strcmp(value.ptr, new_value.ptr) != 0) {
+            fprintf(stderr, "Error: Updated value is not correct, "
+                            "expected (%s) got (%s), at line %d\n",
+                    (char *) value.ptr, (char *) new_value.ptr, __LINE__);
+            exit(1);
+        }
+    } else {
+        fprintf(stderr, "Error: Updated value is not correct, "
+                        "expected type (%d) got (%d), at line %d\n",
+                value.type, new_value.type, __LINE__);
+        exit(1);
+    }
+
+    if ((status = hash_enter(table, &key, &old_value)) != HASH_SUCCESS) {
+        fprintf(stderr, "Error: %ld failed insertion at line %d (%s) \n",
+                test[0].val, __LINE__, error_string(status));
+        exit(1);
+    }
+
 
     /*
      * Delete a key, make sure we can't find it, assure we can find all other
-- 
1.7.2.3



More information about the sssd-devel mailing list