00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include "db.h"
00009 #include "externs.h"
00010 #include "htab.h"
00011 #include "alloc.h"
00012
00013 #include "mudconf.h"
00014
00015 struct string_dict_entry {
00016 char *key;
00017 void *data;
00018 };
00019
00020 static int hrbtab_compare(char *left, char *right, void *arg)
00021 {
00022 return strcasecmp(left, right);
00023 }
00024
00025 void hashinit(RBTAB * htab, int size)
00026 {
00027 memset(htab, 0, sizeof(RBTAB));
00028 htab->tree = rb_init((void *)hrbtab_compare, NULL);
00029 htab->last = NULL;
00030 }
00031
00032
00033
00034
00035
00036
00037 void hashreset(RBTAB * htab)
00038 {
00039 htab->checks = 0;
00040 htab->scans = 0;
00041 htab->hits = 0;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050 void *hashfind(char *str, RBTAB * htab)
00051 {
00052 int hval, numchecks;
00053 struct string_dict_entry *ent;
00054
00055 htab->checks++;
00056 ent = rb_find(htab->tree, str);
00057 if(ent) {
00058 return ent->data;
00059 } else
00060 return (void *)ent;
00061 }
00062
00063
00064
00065
00066
00067
00068 int hashadd(char *str, void *hashdata, RBTAB * htab)
00069 {
00070 struct string_dict_entry *ent = malloc(sizeof(struct string_dict_entry));
00071
00072 if(rb_exists(htab->tree, str))
00073 return (-1);
00074
00075 ent->key = strdup(str);
00076 ent->data = hashdata;
00077
00078 rb_insert(htab->tree, ent->key, ent);
00079 return 0;
00080
00081 }
00082
00083
00084
00085
00086
00087
00088 void hashdelete(char *str, RBTAB * htab)
00089 {
00090 struct string_dict_entry *ent = NULL;
00091
00092 if(!rb_exists(htab->tree, str)) {
00093 return;
00094 }
00095 ent = rb_delete(htab->tree, str);
00096
00097 if(ent) {
00098 if(ent->key)
00099 free(ent->key);
00100 free(ent);
00101 }
00102
00103 return;
00104 }
00105
00106
00107
00108
00109
00110
00111 static int nuke_hash_ent(void *key, void *data, int depth, void *arg)
00112 {
00113 struct string_dict_entry *ent = (struct string_dict_entry *) data;
00114 free(ent->key);
00115 free(ent);
00116 return 1;
00117 }
00118
00119 void hashflush(RBTAB * htab, int size)
00120 {
00121 rb_walk(htab->tree, WALK_POSTORDER, nuke_hash_ent, NULL);
00122 rb_destroy(htab->tree);
00123 htab->tree = rb_init((void *)hrbtab_compare, NULL);
00124 if(htab->last)
00125 free(htab->last);
00126 htab->last = NULL;
00127 }
00128
00129
00130
00131
00132
00133
00134 int hashrepl(char *str, void *hashdata, RBTAB * htab)
00135 {
00136 struct string_dict_entry *ent;
00137
00138 ent = rb_find(htab->tree, str);
00139 if(!ent)
00140 return 0;
00141
00142 ent->data = hashdata;
00143 return 1;
00144 }
00145
00146 struct hashreplstat {
00147 void *old;
00148 void *new;
00149 };
00150
00151 static int hashreplall_cb(void *key, void *data, int depth, void *arg)
00152 {
00153 struct string_dict_entry *ent = (struct string_dict_entry *) data;
00154 struct hashreplstat *repl = (struct hashreplstat *) arg;
00155
00156 if(ent->data == repl->old) {
00157 ent->data = repl->new;
00158 }
00159 return 1;
00160 }
00161
00162 void hashreplall(void *old, void *new, RBTAB * htab)
00163 {
00164 struct hashreplstat repl = { old, new };
00165
00166 rb_walk(htab->tree, WALK_INORDER, hashreplall_cb, &repl);
00167 }
00168
00169
00170
00171
00172
00173
00174 char *hashinfo(const char *tab_name, RBTAB * htab)
00175 {
00176 char *buff;
00177
00178 buff = alloc_mbuf("hashinfo");
00179 sprintf(buff, "%-15s %8d", tab_name, rb_size(htab->tree));
00180 return buff;
00181 }
00182
00183
00184
00185
00186
00187 void *hash_firstentry(RBTAB * htab)
00188 {
00189 struct string_dict_entry *ent;
00190
00191 if(htab->last)
00192 free(htab->last);
00193
00194 ent = rb_search(htab->tree, SEARCH_FIRST, NULL);
00195 if(ent) {
00196 htab->last = strdup(ent->key);
00197 return ent->data;
00198 }
00199 htab->last = NULL;
00200
00201 return NULL;
00202 }
00203
00204 void *hash_nextentry(RBTAB * htab)
00205 {
00206 struct string_dict_entry *ent;
00207
00208 if(!htab->last) {
00209 return hash_firstentry(htab);
00210 }
00211
00212 ent = rb_search(htab->tree, SEARCH_GT, htab->last);
00213 free(htab->last);
00214
00215 if(ent) {
00216 htab->last = strdup(ent->key);
00217 return ent->data;
00218 } else {
00219 htab->last = NULL;
00220 return NULL;
00221 }
00222 }
00223
00224 char *hash_firstkey(RBTAB * htab)
00225 {
00226 struct string_dict_entry *ent;
00227 if(htab->last)
00228 free(htab->last);
00229
00230 ent = rb_search(htab->tree, SEARCH_FIRST, NULL);
00231 if(ent) {
00232 htab->last = strdup(ent->key);
00233 return ent->key;
00234 }
00235 htab->last = NULL;
00236
00237 return NULL;
00238 }
00239
00240 char *hash_nextkey(RBTAB * htab)
00241 {
00242 struct string_dict_entry *ent;
00243
00244 if(!htab->last) {
00245 return hash_firstkey(htab);
00246 }
00247
00248 ent = rb_search(htab->tree, SEARCH_NEXT, htab->last);
00249 free(htab->last);
00250
00251 if(ent) {
00252 htab->last = strdup(ent->key);
00253 return ent->key;
00254 } else {
00255 htab->last = NULL;
00256 return NULL;
00257 }
00258 }