Skip to content

Commit 3c1cae0

Browse files
authored
Merge pull request #3507 from masatake/libutil-htable-update
libutil: revise functions for updating the value for a given key
2 parents 6f72ad6 + da46bf0 commit 3c1cae0

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)