]> git.saurik.com Git - redis.git/blobdiff - dict.c
update makefile to use the new test suite
[redis.git] / dict.c
diff --git a/dict.c b/dict.c
index 0d332b3bd74eef6db602667e0caf93618f43b129..d5010708c37ce6729e3068a170e30029f2fa1d38 100644 (file)
--- a/dict.c
+++ b/dict.c
@@ -41,6 +41,7 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <limits.h>
+#include <sys/time.h>
 
 #include "dict.h"
 #include "zmalloc.h"
@@ -237,6 +238,25 @@ int dictRehash(dict *d, int n) {
     return 1;
 }
 
+long long timeInMilliseconds(void) {
+    struct timeval tv;
+
+    gettimeofday(&tv,NULL);
+    return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
+}
+
+/* Rehash for an amount of time between ms milliseconds and ms+1 milliseconds */
+int dictRehashMilliseconds(dict *d, int ms) {
+    long long start = timeInMilliseconds();
+    int rehashes = 0;
+
+    while(dictRehash(d,100)) {
+        rehashes += 100;
+        if (timeInMilliseconds()-start > ms) break;
+    }
+    return rehashes;
+}
+
 /* This function performs just a step of rehashing, and only if there are
  * not iterators bound to our hash table. When we have iterators in the middle
  * of a rehashing we can't mess with the two hash tables otherwise some element
@@ -403,6 +423,13 @@ dictEntry *dictFind(dict *d, const void *key)
     return NULL;
 }
 
+void *dictFetchValue(dict *d, const void *key) {
+    dictEntry *he;
+
+    he = dictFind(d,key);
+    return he ? dictGetEntryVal(he) : NULL;
+}
+
 dictIterator *dictGetIterator(dict *d)
 {
     dictIterator *iter = _dictAlloc(sizeof(*iter));
@@ -527,7 +554,7 @@ static unsigned long _dictNextPower(unsigned long size)
  * index is always returned in the context of the second (new) hash table. */
 static int _dictKeyIndex(dict *d, const void *key)
 {
-    unsigned int h, h1, h2;
+    unsigned int h, idx, table;
     dictEntry *he;
 
     /* Expand the hashtable if needed */
@@ -535,24 +562,18 @@ static int _dictKeyIndex(dict *d, const void *key)
         return -1;
     /* Compute the key hash value */
     h = dictHashKey(d, key);
-    h1 = h & d->ht[0].sizemask;
-    h2 = h & d->ht[1].sizemask;
-    /* Search if this slot does not already contain the given key */
-    he = d->ht[0].table[h1];
-    while(he) {
-        if (dictCompareHashKeys(d, key, he->key))
-            return -1;
-        he = he->next;
-    }
-    if (!dictIsRehashing(d)) return h1;
-    /* Check the second hash table */
-    he = d->ht[1].table[h2];
-    while(he) {
-        if (dictCompareHashKeys(d, key, he->key))
-            return -1;
-        he = he->next;
+    for (table = 0; table <= 1; table++) {
+        idx = h & d->ht[table].sizemask;
+        /* Search if this slot does not already contain the given key */
+        he = d->ht[table].table[idx];
+        while(he) {
+            if (dictCompareHashKeys(d, key, he->key))
+                return -1;
+            he = he->next;
+        }
+        if (!dictIsRehashing(d)) break;
     }
-    return h2;
+    return idx;
 }
 
 void dictEmpty(dict *d) {