Commit 110ce71b authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Add consistency checks.

parent 46b35b2c
...@@ -31,6 +31,22 @@ struct Hashtable_ { ...@@ -31,6 +31,22 @@ struct Hashtable_ {
}; };
}*/ }*/
#ifdef DEBUG
bool Hashtable_isConsistent(Hashtable* this) {
int items = 0;
for (int i = 0; i < this->size; i++) {
HashtableItem* bucket = this->buckets[i];
while (bucket) {
items++;
bucket = bucket->next;
}
}
return items == this->items;
}
#endif
HashtableItem* HashtableItem_new(int key, void* value) { HashtableItem* HashtableItem_new(int key, void* value) {
HashtableItem* this; HashtableItem* this;
...@@ -45,13 +61,16 @@ Hashtable* Hashtable_new(int size, bool owner) { ...@@ -45,13 +61,16 @@ Hashtable* Hashtable_new(int size, bool owner) {
Hashtable* this; Hashtable* this;
this = (Hashtable*) malloc(sizeof(Hashtable)); this = (Hashtable*) malloc(sizeof(Hashtable));
this->items = 0;
this->size = size; this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size); this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->owner = owner; this->owner = owner;
assert(Hashtable_isConsistent(this));
return this; return this;
} }
void Hashtable_delete(Hashtable* this) { void Hashtable_delete(Hashtable* this) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
while (walk != NULL) { while (walk != NULL) {
...@@ -67,6 +86,7 @@ void Hashtable_delete(Hashtable* this) { ...@@ -67,6 +86,7 @@ void Hashtable_delete(Hashtable* this) {
} }
inline int Hashtable_size(Hashtable* this) { inline int Hashtable_size(Hashtable* this) {
assert(Hashtable_isConsistent(this));
return this->items; return this->items;
} }
...@@ -85,47 +105,53 @@ void Hashtable_put(Hashtable* this, int key, void* value) { ...@@ -85,47 +105,53 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
break; break;
} else } else
bucketPtr = &((*bucketPtr)->next); bucketPtr = &((*bucketPtr)->next);
assert(Hashtable_isConsistent(this));
} }
void* Hashtable_remove(Hashtable* this, int key) { void* Hashtable_remove(Hashtable* this, int key) {
int index = key % this->size; int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) assert(Hashtable_isConsistent(this));
if (*bucketPtr == NULL) {
return NULL; HashtableItem** bucket;
break; for (bucket = &(this->buckets[index]); *bucket; bucket = &((*bucket)->next) ) {
} else if ((*bucketPtr)->key == key) { if ((*bucket)->key == key) {
void* savedValue = (*bucketPtr)->value; void* value = (*bucket)->value;
HashtableItem* savedNext = (*bucketPtr)->next; HashtableItem* next = (*bucket)->next;
free(*bucketPtr); free(*bucket);
(*bucketPtr) = savedNext; (*bucket) = next;
this->items--; this->items--;
if (this->owner) { if (this->owner) {
free(savedValue); free(value);
assert(Hashtable_isConsistent(this));
return NULL; return NULL;
} else { } else {
return savedValue; assert(Hashtable_isConsistent(this));
return value;
} }
} else }
bucketPtr = &((*bucketPtr)->next); }
assert(Hashtable_isConsistent(this));
return NULL;
} }
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key) { inline void* Hashtable_get(Hashtable* this, int key) {
int index = key % this->size; int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index]; HashtableItem* bucketPtr = this->buckets[index];
// fprintf(stderr, "%d -> %d\n", key, index);
while (true) { while (true) {
if (bucketPtr == NULL) { if (bucketPtr == NULL) {
assert(Hashtable_isConsistent(this));
return NULL; return NULL;
} else if (bucketPtr->key == key) { } else if (bucketPtr->key == key) {
assert(Hashtable_isConsistent(this));
return bucketPtr->value; return bucketPtr->value;
} else } else
bucketPtr = bucketPtr->next; bucketPtr = bucketPtr->next;
// fprintf(stderr, "*\n");
} }
} }
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) { void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
while (walk != NULL) { while (walk != NULL) {
...@@ -133,4 +159,5 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData ...@@ -133,4 +159,5 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData
walk = walk->next; walk = walk->next;
} }
} }
assert(Hashtable_isConsistent(this));
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment