resize(capacity << 1);
struct hashlistnode<_Key, _Val> *search;
+ struct hashlistnode<_Key, _Val> *first = NULL;
- unsigned int index = hash_function(key);
+ unsigned int index = hash_function(key) & capacitymask;
+ unsigned int oindex = index;
do {
- index &= capacitymask;
search = &table[index];
if (!search->key) {
//key is null, probably done
- break;
+ if (!search->val)
+ break;
+ if (first == NULL)
+ first = search;
}
if (equals(search->key, key)) {
search->val = val;
return;
}
- index++;
+ index = (index + 1) & capacitymask;
+ if (index == oindex) {
+ if (first == NULL)
+ exit(-1);
+ break;
+ }
} while (true);
- search->key = key;
- search->val = val;
+ if (first != NULL) {
+ first->key = key;
+ first->val = val;
+ } else {
+ search->key = key;
+ search->val = val;
+ }
size++;
}
}
unsigned int oindex = hash_function(key) & capacitymask;
- unsigned int index=oindex;
+ unsigned int index = oindex;
do {
search = &table[index];
if (!search->key) {
*/
_Val remove(_Key key) {
struct hashlistnode<_Key, _Val> *search;
+ struct hashlistnode<_Key, _Val> *replace;
/* HashTable cannot handle 0 as a key */
if (!key) {
if (!search->key) {
if (!search->val)
break;
- } else
- if (equals(search->key, key)) {
- _Val v=search->val;
- //empty out this bin
- search->val=(_Val) 1;
- search->key=0;
- size--;
- return v;
+ } else {
+ // The case where an item is found
+ if (equals(search->key, key)) {
+ unsigned int j = index;
+ _Val v = search->val;
+ size--;
+
+ // Idea: keep bins contiguous
+ while (true) {
+ search->val = 0;
+ search->key = 0;
+
+ while (true) {
+ j = (j + 1) & capacitymask;
+ replace = &table[j];
+
+ if (!replace->key && !replace->val) {
+ return v;
+ }
+
+ unsigned int hash = hash_function(replace->key) & capacitymask;
+ if (index <= j && index < hash && hash <= j)
+ continue;
+ else if (index > j && (index < hash || hash <= j) )
+ continue;
+ else
+ break;
+ }
+
+ table[index] = table[j];
+ index = j;
+ search = &table[index];
+ }
+ }
}
index++;
} while (true);