summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/hashtable.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/lib/hashtable.c b/lib/hashtable.c
index f0056ac..f4d5795 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -247,6 +247,34 @@ int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
return 0;
}
+/*
+ * Compare an existing entry with the desired key, and overwrite if the action
+ * is ENTER. This is simply a helper function for hsearch_r().
+ */
+static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
+ ENTRY **retval, struct hsearch_data *htab, int flag,
+ unsigned int hval, unsigned int idx)
+{
+ if (htab->table[idx].used == hval
+ && strcmp(item.key, htab->table[idx].entry.key) == 0) {
+ /* Overwrite existing value? */
+ if ((action == ENTER) && (item.data != NULL)) {
+ free(htab->table[idx].entry.data);
+ htab->table[idx].entry.data = strdup(item.data);
+ if (!htab->table[idx].entry.data) {
+ __set_errno(ENOMEM);
+ *retval = NULL;
+ return 0;
+ }
+ }
+ /* return found entry */
+ *retval = &htab->table[idx].entry;
+ return idx;
+ }
+ /* keep searching */
+ return -1;
+}
+
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
struct hsearch_data *htab, int flag)
{
@@ -255,6 +283,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
unsigned int len = strlen(item.key);
unsigned int idx;
unsigned int first_deleted = 0;
+ int ret;
/* Compute an value for the given string. Perhaps use a better method. */
hval = len;
@@ -286,23 +315,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
&& !first_deleted)
first_deleted = idx;
- if (htab->table[idx].used == hval
- && strcmp(item.key, htab->table[idx].entry.key) == 0) {
- /* Overwrite existing value? */
- if ((action == ENTER) && (item.data != NULL)) {
- free(htab->table[idx].entry.data);
- htab->table[idx].entry.data =
- strdup(item.data);
- if (!htab->table[idx].entry.data) {
- __set_errno(ENOMEM);
- *retval = NULL;
- return 0;
- }
- }
- /* return found entry */
- *retval = &htab->table[idx].entry;
- return idx;
- }
+ ret = _compare_and_overwrite_entry(item, action, retval, htab,
+ flag, hval, idx);
+ if (ret != -1)
+ return ret;
/*
* Second hash function:
@@ -328,23 +344,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
break;
/* If entry is found use it. */
- if ((htab->table[idx].used == hval)
- && strcmp(item.key, htab->table[idx].entry.key) == 0) {
- /* Overwrite existing value? */
- if ((action == ENTER) && (item.data != NULL)) {
- free(htab->table[idx].entry.data);
- htab->table[idx].entry.data =
- strdup(item.data);
- if (!htab->table[idx].entry.data) {
- __set_errno(ENOMEM);
- *retval = NULL;
- return 0;
- }
- }
- /* return found entry */
- *retval = &htab->table[idx].entry;
- return idx;
- }
+ ret = _compare_and_overwrite_entry(item, action, retval,
+ htab, flag, hval, idx);
+ if (ret != -1)
+ return ret;
}
while (htab->table[idx].used);
}