struct Hashlistnode {
_Key key;
_Val val;
- uint hashcode;
- struct Hashlistnode<_Key, _Val> *next;
- struct Hashlistnode<_Key, _Val> *prev;
};
template<typename _Key, int _Shift, typename _KeyInt>
* @param factor Sets the percentage full before the hashtable is
* resized. Default ratio 0.5.
*/
- Hashtable(unsigned int initialcapacity = 32, double factor = 0.5) {
+ Hashtable(unsigned int initialcapacity = 16, double factor = 0.5) {
// Allocate space for the hash table
table = (struct Hashlistnode<_Key, _Val> *)ourcalloc(initialcapacity, sizeof(struct Hashlistnode<_Key, _Val>));
zero = NULL;
threshold = (unsigned int)(initialcapacity * loadfactor);
Size = 0; // Initial number of elements in the hash
- tail = list = NULL;
}
Hashtable<_Key, _Val, _KeyInt, _Shift, hash_function, equals> *clone() {
Hashtable<_Key, _Val, _KeyInt, _Shift, hash_function, equals> *ctable = new Hashtable<_Key, _Val, _KeyInt, _Shift, hash_function, equals> (capacity, loadfactor);
- struct Hashlistnode<_Key, _Val> *ptr = list;
- while (ptr != NULL) {
- ctable->put(ptr->key, ptr->val);
- ptr = ptr->next;
+ if (zero)
+ ctable->put(zero->key, zero->val);
+
+ for(unsigned int i=0; i<capacity; i++) {
+ struct Hashlistnode<_Key, _Val> ptr = table[i];
+ if (ptr.key && ptr.val)
+ ctable->put(ptr.key, ptr.val);
}
return ctable;
}
zero = NULL;
}
Size = 0;
- tail = list = NULL;
}
/** Doesn't work with zero value */
zero = NULL;
}
Size = 0;
- tail = list = NULL;
}
void resetAndDeleteVals() {
zero = NULL;
}
Size = 0;
- tail = list = NULL;
}
void resetAndFreeVals() {
zero = NULL;
}
Size = 0;
- tail = list = NULL;
}
/**
* @param val The value to store in the table
*/
_Val put(_Key key, _Val val) {
- /* Hashtable cannot handle 0 as a key */
+ ASSERT(val);
if (!key) {
_Val oldval;
if (!zero) {
zero = (struct Hashlistnode<_Key, _Val> *)ourmalloc(sizeof(struct Hashlistnode<_Key, _Val>));
- zero->next = list;
- if (list != NULL)
- list->prev = zero;
- else
- tail = zero;
- list = zero;
Size++;
oldval = (_Val) 0;
} else
//key is null, probably done
break;
}
- if (search->hashcode == hashcode)
+ unsigned int searchhashcode = hash_function(search->key);
+ if (searchhashcode == hashcode)
if (equals(search->key, key)) {
_Val oldval = search->val;
search->val = val;
search->key = key;
search->val = val;
- search->hashcode = hashcode;
- search->next = list;
- if (list == NULL)
- tail = search;
- else
- list->prev = search;
- list = search;
Size++;
return (_Val) 0;
}
if (!search->key) {
if (!search->val)
break;
- } else
- if (hashcode == search->hashcode)
- if (equals(search->key, key))
- return search->val;
+ } else {
+ unsigned int searchhashcode = hash_function(search->key);
+ if (hashcode == searchhashcode)
+ if (equals(search->key, key))
+ return search->val;
+ }
index++;
index &= capacitymask;
if (index == oindex)
return (_Val)0;
} else {
_Val v = zero->val;
- if (zero->next != NULL)
- zero->next->prev = zero->prev;
- else
- tail = zero->prev;
-
- if (zero->prev != NULL)
- zero->prev->next = zero->next;
- else
- list = zero->next;
ourfree(zero);
zero = NULL;
if (!search->key) {
if (!search->val)
break;
- } else
- if (hashcode == search->hashcode)
- if (equals(search->key, key)) {
- _Val v = search->val;
- //empty out this bin
- search->val = (_Val) 1;
- search->key = 0;
-
- if (search->next != NULL)
- search->next->prev = search->prev;
- else
- tail = search->prev;
-
- if (search->prev != NULL)
- search->prev->next = search->next;
- else
- list = search->next;
-
- Size--;
- return v;
- }
+ } else {
+ unsigned int searchhashcode = hash_function(search->key);
+ if (hashcode == searchhashcode)
+ if (equals(search->key, key)) {
+ _Val v = search->val;
+ //empty out this bin
+ search->val = (_Val) 1;
+ search->key = 0;
+ Size--;
+ return v;
+ }
+ }
index++;
} while (true);
return (_Val)0;
if (!search->key) {
if (!search->val)
break;
- } else
- if (hashcode == search->hashcode)
- if (equals(search->key, key))
- return true;
+ } else {
+ unsigned int searchhashcode = hash_function(search->key);
+ if (hashcode == searchhashcode)
+ if (equals(search->key, key))
+ return true;
+ }
index++;
} while (true);
return false;
table = newtable; // Update the global hashtable upon resize()
capacity = newsize;
capacitymask = newsize - 1;
- list = tail = NULL;
threshold = (unsigned int)(newsize * loadfactor);
struct Hashlistnode<_Key, _Val> *bin = &oldtable[0];
if (!key)
continue;
- unsigned int hashcode = bin->hashcode;
+ unsigned int hashcode = hash_function(bin->key);
unsigned int index = hashcode;
do {
index &= capacitymask;
index++;
} while (search->key);
- if (tail == NULL)
- tail = search;
- search->next = list;
- if (list != NULL)
- list->prev = search;
- list = search;
- search->hashcode = hashcode;
search->key = key;
search->val = bin->val;
}
unsigned int getCapacity() {return capacity;}
struct Hashlistnode<_Key, _Val> *table;
struct Hashlistnode<_Key, _Val> *zero;
- struct Hashlistnode<_Key, _Val> *list;
- struct Hashlistnode<_Key, _Val> *tail;
unsigned int capacity;
unsigned int Size;
private: