diff options
Diffstat (limited to 'lib/hashtable.c')
| -rw-r--r-- | lib/hashtable.c | 71 | 
1 files changed, 37 insertions, 34 deletions
| diff --git a/lib/hashtable.c b/lib/hashtable.c index f0056acf6..f4d579505 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);  	} |