#include "goomsl_hash.h" #include #include static GoomHashEntry *entry_new(const char *key, HashValue value) { int len = strlen(key); GoomHashEntry *entry = (GoomHashEntry*)malloc(sizeof(GoomHashEntry)); entry->key = (char *)malloc(len+1); memcpy(entry->key,key,len+1); entry->value = value; entry->lower = NULL; entry->upper = NULL; return entry; } static void entry_free(GoomHashEntry *entry) { if (entry!=NULL) { entry_free(entry->lower); entry_free(entry->upper); free(entry->key); free(entry); } } static void entry_put(GoomHashEntry *entry, const char *key, HashValue value) { int cmp = strcmp(key,entry->key); if (cmp==0) { entry->value = value; } else if (cmp > 0) { if (entry->upper == NULL) entry->upper = entry_new(key,value); else entry_put(entry->upper, key, value); } else { if (entry->lower == NULL) entry->lower = entry_new(key,value); else entry_put(entry->lower, key, value); } } static HashValue *entry_get(GoomHashEntry *entry, const char *key) { int cmp; if (entry==NULL) return NULL; cmp = strcmp(key,entry->key); if (cmp > 0) return entry_get(entry->upper, key); else if (cmp < 0) return entry_get(entry->lower, key); else return &(entry->value); } GoomHash *goom_hash_new() { GoomHash *_this = (GoomHash*)malloc(sizeof(GoomHash)); _this->root = NULL; _this->number_of_puts = 0; return _this; } void goom_hash_free(GoomHash *_this) { entry_free(_this->root); free(_this); } void goom_hash_put(GoomHash *_this, const char *key, HashValue value) { _this->number_of_puts += 1; if (_this->root == NULL) _this->root = entry_new(key,value); else entry_put(_this->root,key,value); } HashValue *goom_hash_get(GoomHash *_this, const char *key) { if (_this == NULL) return NULL; return entry_get(_this->root,key); } void goom_hash_put_int(GoomHash *_this, const char *key, int i) { HashValue value; value.i = i; goom_hash_put(_this,key,value); } void goom_hash_put_float(GoomHash *_this, const char *key, float f) { HashValue value; value.f = f; goom_hash_put(_this,key,value); } void goom_hash_put_ptr(GoomHash *_this, const char *key, void *ptr) { HashValue value; value.ptr = ptr; goom_hash_put(_this,key,value); } /* FOR EACH */ static void _goom_hash_for_each(GoomHash *_this, GoomHashEntry *entry, GH_Func func) { if (entry == NULL) return; func(_this, entry->key, &(entry->value)); _goom_hash_for_each(_this, entry->lower, func); _goom_hash_for_each(_this, entry->upper, func); } void goom_hash_for_each(GoomHash *_this, GH_Func func) { _goom_hash_for_each(_this, _this->root, func); } int goom_hash_number_of_puts(GoomHash *_this) { return _this->number_of_puts; }