#include <stdarg.h>
#include <assert.h>
#include <limits.h>
+#include <sys/time.h>
#include "dict.h"
#include "zmalloc.h"
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
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));
* 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 */
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) {