1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#include "goomsl_hash.h"
#include <string.h>
#include <stdlib.h>
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;
}
|