summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2011-11-08 16:57:20 +0100
committerantirez <antirez@gmail.com>2011-11-08 16:57:20 +0100
commit71a50956b1ff6b45b8265afa8e7e0264c465cec8 (patch)
tree489def63944b5bb36b367fb43f351151cb384f85 /src
parent66d8818cb751ab23e70e82fc5ab1017399f49109 (diff)
downloadredis-71a50956b1ff6b45b8265afa8e7e0264c465cec8.tar.gz
dict.c: added two lower level methods for directly manipulating hash entries. This is useful in order to set 64 bit integers as values directly inside the hash entry (in order to save memory), without casting, and even in 32 bit builds.
Diffstat (limited to 'src')
-rw-r--r--src/dict.c41
-rw-r--r--src/dict.h2
2 files changed, 40 insertions, 3 deletions
diff --git a/src/dict.c b/src/dict.c
index f98fdd0ee..9d3368412 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -259,6 +259,30 @@ static void _dictRehashStep(dict *d) {
/* Add an element to the target hash table */
int dictAdd(dict *d, void *key, void *val)
{
+ dictEntry *entry = dictAddRaw(d,key);
+
+ if (!entry) return DICT_ERR;
+ dictSetHashVal(d, entry, val);
+ return DICT_OK;
+}
+
+/* Low level add. This function adds the entry but instead of setting
+ * a value returns the dictEntry structure to the user, that will make
+ * sure to fill the value field as he wishes.
+ *
+ * This function is also directly expoed to user API to be called
+ * mainly in order to store non-pointers inside the hash value, example:
+ *
+ * entry = dictAddRaw(dict,mykey);
+ * if (entry != NULL) dictSetValSignedInteger(entry,1000);
+ *
+ * Return values:
+ *
+ * If key already exists NULL is returned.
+ * If key was added, the hash entry is returned to be manipulated by the caller.
+ */
+dictEntry *dictAddRaw(dict *d, void *key)
+{
int index;
dictEntry *entry;
dictht *ht;
@@ -268,7 +292,7 @@ int dictAdd(dict *d, void *key, void *val)
/* Get the index of the new element, or -1 if
* the element already exists. */
if ((index = _dictKeyIndex(d, key)) == -1)
- return DICT_ERR;
+ return NULL;
/* Allocate the memory and store the new entry */
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
@@ -279,8 +303,7 @@ int dictAdd(dict *d, void *key, void *val)
/* Set the hash entry fields. */
dictSetHashKey(d, entry, key);
- dictSetHashVal(d, entry, val);
- return DICT_OK;
+ return entry;
}
/* Add an element, discarding the old if the key already exists.
@@ -308,6 +331,18 @@ int dictReplace(dict *d, void *key, void *val)
return 0;
}
+/* dictReplaceRaw() is simply a version of dictAddRaw() that always
+ * returns the hash entry of the specified key, even if the key already
+ * exists and can't be added (in that case the entry of the already
+ * existing key is returned.)
+ *
+ * See dictAddRaw() for more information. */
+dictEntry *dictReplaceRaw(dict *d, void *key) {
+ dictEntry *entry = dictFind(d,key);
+
+ return entry ? entry : dictAddRaw(d,key);
+}
+
/* Search and remove an element */
static int dictGenericDelete(dict *d, const void *key, int nofree)
{
diff --git a/src/dict.h b/src/dict.h
index 31cd65646..23b1fc52e 100644
--- a/src/dict.h
+++ b/src/dict.h
@@ -133,7 +133,9 @@ typedef struct dictIterator {
dict *dictCreate(dictType *type, void *privDataPtr);
int dictExpand(dict *d, unsigned long size);
int dictAdd(dict *d, void *key, void *val);
+dictEntry *dictAddRaw(dict *d, void *key);
int dictReplace(dict *d, void *key, void *val);
+dictEntry *dictReplaceRaw(dict *d, void *key);
int dictDelete(dict *d, const void *key);
int dictDeleteNoFree(dict *d, const void *key);
void dictRelease(dict *d);