Skip to content

Commit da46bf0

Browse files
committed
libutil: revise functions for updating the value for a given key
The original hashTableUpdateItem() replaces not only the value but the key. So we cannot add "const" modifier to the key parameter. This change revises the function. The new hashTableUpdateItem() never replaces the key; if key is not found, it just returns false. So we can add the const modifier to the key parameter. In addition we introduces a new function, hashTableUpdateOrPutItem(). hashTableUpdateOrPutItem() don't replace the key as far as the key exits in the hash table. However, we don't add the const modifier to the key parameter because the key and the value is put to the the hash table if the key doesn't exist in the hash table. These two are tested in tutil target. Signed-off-by: Masatake YAMATO <[email protected]>
1 parent 6f72ad6 commit da46bf0

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

dsl/optscript.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2129,7 +2129,11 @@ dict_op_def (EsObject* dict, EsObject *key, EsObject *val)
21292129
key = es_object_ref (key);
21302130
val = es_object_ref (val);
21312131

2132-
hashTableUpdateItem (t, key, val);
2132+
if (hashTableUpdateOrPutItem (t, key, val))
2133+
{
2134+
/* A key in the hashtable is reused. */
2135+
es_object_unref (key);
2136+
}
21332137
}
21342138

21352139
static bool

extra-cmds/utiltest.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,33 @@
88
#include "general.h"
99

1010
#include "acutest.h"
11+
#include "htable.h"
1112
#include "routines.h"
1213
#include <string.h>
1314

15+
void test_htable_update(void)
16+
{
17+
hashTable *htable = hashTableNew (3, hashCstrhash, hashCstreq,
18+
eFree, NULL);
19+
TEST_CHECK(htable != NULL);
20+
21+
hashTablePutItem (htable, strdup("a"), "A");
22+
TEST_CHECK (hashTableUpdateItem (htable, "a", "B") == true);
23+
TEST_CHECK (hashTableUpdateItem (htable, "b", "B") == false);
24+
TEST_CHECK (strcmp (hashTableGetItem (htable, "a"), "B") == 0);
25+
TEST_CHECK (hashTableUpdateOrPutItem (htable, "a", "C") == true);
26+
TEST_CHECK (hashTableUpdateOrPutItem (htable, strdup("x"), "X") == false);
27+
TEST_CHECK (strcmp (hashTableGetItem (htable, "x"), "X") == 0);
28+
hashTableDelete(htable);
29+
}
30+
1431
void test_routines_strrstr(void)
1532
{
1633
TEST_CHECK(strcmp(strrstr("abcdcdb", "cd"), "cdb") == 0);
1734
}
1835

1936
TEST_LIST = {
37+
{ "htable/update", test_htable_update },
2038
{ "routines/strrstr", test_routines_strrstr },
2139
{ NULL, NULL } /* zeroed record marking the end of the list */
2240
};

main/htable.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ static void entry_reset (hentry* entry,
8181
keyfreefn (entry->key);
8282
if (valfreefn)
8383
valfreefn (entry->value);
84-
entry->key = newkey;
84+
85+
if (keyfreefn)
86+
entry->key = newkey;
8587
entry->value = newval;
8688
}
8789

@@ -346,14 +348,25 @@ extern bool hashTableDeleteItem (hashTable *htable, const void *key)
346348
return r;
347349
}
348350

349-
extern bool hashTableUpdateItem (hashTable *htable, void *key, void *value)
351+
extern bool hashTableUpdateItem (hashTable *htable, const void *key, void *value)
352+
{
353+
unsigned int h, i;
354+
355+
h = htable->hashfn (key);
356+
i = h % htable->size;
357+
bool r = entry_update(htable->table[i], (void *)key, value,
358+
htable->equalfn, NULL, htable->valfreefn);
359+
return r;
360+
}
361+
362+
extern bool hashTableUpdateOrPutItem (hashTable *htable, void *key, void *value)
350363
{
351364
unsigned int h, i;
352365

353366
h = htable->hashfn (key);
354367
i = h % htable->size;
355368
bool r = entry_update(htable->table[i], key, value,
356-
htable->equalfn, htable->keyfreefn, htable->valfreefn);
369+
htable->equalfn, NULL, htable->valfreefn);
357370
if (!r)
358371
hashTablePutItem0(htable, key, value, h);
359372

main/htable.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,19 @@ extern void hashTablePutItem (hashTable *htable, void *key, void *valu
7070
extern void* hashTableGetItem (hashTable *htable, const void * key);
7171
extern bool hashTableHasItem (hashTable * htable, const void * key);
7272
extern bool hashTableDeleteItem (hashTable *htable, const void *key);
73-
extern bool hashTableUpdateItem (hashTable *htable, void *key, void *value);
73+
74+
/* If KEY is found, this function updates the value for KEY and returns true.
75+
* If KEY is not found, this function just returns false.
76+
*
77+
* KEY is just referred. The HTABLE takes the ownership of VALUE when KEY is found. */
78+
extern bool hashTableUpdateItem (hashTable *htable, const void *key, void *value);
79+
80+
/* If KEY is found, this function updates the value for KEY and returns true.
81+
* If KEY is not found, this function adds KEY and VALUE and returns false.
82+
*
83+
* The HTABLE takes the ownership of KEY only if KEY is not found.
84+
* The HTABLE takes the ownership of VALUE either when KEY is found or not. */
85+
extern bool hashTableUpdateOrPutItem (hashTable *htable, void *key, void *value);
7486

7587
/* Return true if proc never returns false; proc returns true for all
7688
* the items, or htable holds no item.

0 commit comments

Comments
 (0)