aboutsummaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorWaldemar Celes <celes@tecgraf.puc-rio.br>1994-10-11 09:59:49 -0300
committerWaldemar Celes <celes@tecgraf.puc-rio.br>1994-10-11 09:59:49 -0300
commitd107d5bfd21afb490616cc8f082d965ff9fa9f58 (patch)
treeb0803718e972897cc2e7207fdcf9dca0054c0a43 /hash.c
parentd7d7b477bb4e09fc69e31ccf21106a2c07fa441d (diff)
downloadlua-d107d5bfd21afb490616cc8f082d965ff9fa9f58.tar.gz
lua-d107d5bfd21afb490616cc8f082d965ff9fa9f58.tar.bz2
lua-d107d5bfd21afb490616cc8f082d965ff9fa9f58.zip
implementacao de busca no campo godparent em substituicao
ao campo parents.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c118
1 files changed, 46 insertions, 72 deletions
diff --git a/hash.c b/hash.c
index 6ccdc932..916a0d43 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
3** hash manager for lua 3** hash manager for lua
4*/ 4*/
5 5
6char *rcs_hash="$Id: hash.c,v 2.6 1994/08/17 17:41:23 celes Exp celes $"; 6char *rcs_hash="$Id: hash.c,v 2.7 1994/09/08 15:27:10 celes Exp celes $";
7 7
8#include <string.h> 8#include <string.h>
9#include <stdlib.h> 9#include <stdlib.h>
@@ -33,19 +33,14 @@ char *rcs_hash="$Id: hash.c,v 2.6 1994/08/17 17:41:23 celes Exp celes $";
33#define REHASH_LIMIT 0.70 /* avoid more than this % full */ 33#define REHASH_LIMIT 0.70 /* avoid more than this % full */
34 34
35 35
36typedef struct ArrayList 36static Hash *listhead = NULL;
37{
38 Hash *array;
39 struct ArrayList *next;
40} ArrayList;
41
42static ArrayList *listhead = NULL;
43 37
44 38
45 39
46/* hash dimensions values */ 40/* hash dimensions values */
47static int dimensions[] = 41static int dimensions[] =
48 {7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, 12853, 25717, 51437, 0}; 42 {3, 5, 7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421,
43 12853, 25717, 51437, 0};
49static int redimension (int nhash) 44static int redimension (int nhash)
50{ 45{
51 int i; 46 int i;
@@ -89,23 +84,27 @@ static int index (Hash *t, Object *ref) /* hash function */
89 } 84 }
90} 85}
91 86
87static int equalObj (Object *t1, Object *t2)
88{
89 if (tag(t1) != tag(t2)) return 0;
90 switch (tag(t1))
91 {
92 case T_NUMBER: return nvalue(t1) == nvalue(t2);
93 case T_STRING: return streq(svalue(t1), svalue(t2));
94 default: return uvalue(t1) == uvalue(t2);
95 }
96}
97
92static int present (Hash *t, Object *ref) 98static int present (Hash *t, Object *ref)
93{ 99{
94 int h = index(t, ref); 100 int h = index(t, ref);
95 if (h < 0) return h; 101 if (h < 0) return h;
96 while (tag(ref(node(t, h))) != T_NIL) 102 while (tag(ref(node(t, h))) != T_NIL)
97 { 103 {
98 if (tag(ref) == T_NUMBER && tag(ref(node(t, h))) == T_NUMBER && 104 if (equalObj(ref, ref(node(t, h))))
99 nvalue(ref) == nvalue(ref(node(t, h))) 105 return h;
100 ) return h;
101 if (tag(ref) == T_STRING && tag(ref(node(t, h))) == T_STRING &&
102 streq(svalue(ref),svalue(ref(node(t, h))))
103 ) return h;
104 if (tag(ref) == tag(ref(node(t, h))) &&
105 uvalue(ref) == uvalue(ref(node(t, h))) /* all others are pointers */
106 ) return h;
107 h = (h+1) % nhash(t); 106 h = (h+1) % nhash(t);
108 } 107 }
109 return h; 108 return h;
110} 109}
111 110
@@ -138,7 +137,7 @@ static Hash *hashcreate (int nhash)
138 lua_error ("not enough memory"); 137 lua_error ("not enough memory");
139 return NULL; 138 return NULL;
140 } 139 }
141 nhash = redimension(nhash); 140 nhash = redimension((int)((float)nhash/REHASH_LIMIT));
142 141
143 nodevector(t) = hashnodecreate(nhash); 142 nodevector(t) = hashnodecreate(nhash);
144 if (nodevector(t) == NULL) 143 if (nodevector(t) == NULL)
@@ -187,43 +186,36 @@ void lua_hashmark (Hash *h)
187*/ 186*/
188void lua_hashcollector (void) 187void lua_hashcollector (void)
189{ 188{
190 ArrayList *curr = listhead, *prev = NULL; 189 Hash *curr_array = listhead, *prev = NULL;
191 while (curr != NULL) 190 while (curr_array != NULL)
192 { 191 {
193 ArrayList *next = curr->next; 192 Hash *next = curr_array->next;
194 if (markarray(curr->array) != 1) 193 if (markarray(curr_array) != 1)
195 { 194 {
196 if (prev == NULL) listhead = next; 195 if (prev == NULL) listhead = next;
197 else prev->next = next; 196 else prev->next = next;
198 hashdelete(curr->array); 197 hashdelete(curr_array);
199 free(curr);
200 } 198 }
201 else 199 else
202 { 200 {
203 markarray(curr->array) = 0; 201 markarray(curr_array) = 0;
204 prev = curr; 202 prev = curr_array;
205 } 203 }
206 curr = next; 204 curr_array = next;
207 } 205 }
208} 206}
209 207
210 208
211/* 209/*
212** Create a new array 210** Create a new array
213** This function insert the new array at array list. It also 211** This function inserts the new array in the array list. It also
214** execute garbage collection if the number of array created 212** executes garbage collection if the number of arrays created
215** exceed a pre-defined range. 213** exceed a pre-defined range.
216*/ 214*/
217Hash *lua_createarray (int nhash) 215Hash *lua_createarray (int nhash)
218{ 216{
219 ArrayList *new = new(ArrayList); 217 Hash *array = hashcreate(nhash);
220 if (new == NULL) 218 if (array == NULL)
221 {
222 lua_error ("not enough memory");
223 return NULL;
224 }
225 new->array = hashcreate(nhash);
226 if (new->array == NULL)
227 { 219 {
228 lua_error ("not enough memory"); 220 lua_error ("not enough memory");
229 return NULL; 221 return NULL;
@@ -233,9 +225,9 @@ Hash *lua_createarray (int nhash)
233 lua_pack(); 225 lua_pack();
234 226
235 lua_nentity++; 227 lua_nentity++;
236 new->next = listhead; 228 array->next = listhead;
237 listhead = new; 229 listhead = array;
238 return new->array; 230 return array;
239} 231}
240 232
241 233
@@ -268,7 +260,7 @@ Object *lua_hashget (Hash *t, Object *ref)
268 static int count = 1000; 260 static int count = 1000;
269 static Object nil_obj = {T_NIL, {NULL}}; 261 static Object nil_obj = {T_NIL, {NULL}};
270 int h = present(t, ref); 262 int h = present(t, ref);
271 if (h < 0) return NULL; 263 if (h < 0) return &nil_obj;
272 if (tag(ref(node(t, h))) != T_NIL) return val(node(t, h)); 264 if (tag(ref(node(t, h))) != T_NIL) return val(node(t, h));
273 if (--count == 0) 265 if (--count == 0)
274 { 266 {
@@ -276,11 +268,13 @@ Object *lua_hashget (Hash *t, Object *ref)
276 return &nil_obj; 268 return &nil_obj;
277 } 269 }
278 270
279 { /* check "parent" field */ 271 { /* check "parent" or "godparent" field */
280 Hash *p; 272 Hash *p;
281 Object parent; 273 Object parent;
282 tag(&parent) = T_STRING; 274 Object godparent;
283 svalue(&parent) = "parent"; 275 tag(&parent) = T_STRING; svalue(&parent) = "parent";
276 tag(&godparent) = T_STRING; svalue(&godparent) = "godparent";
277
284 h = present(t, &parent); /* assert(h >= 0); */ 278 h = present(t, &parent); /* assert(h >= 0); */
285 p = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ? 279 p = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ?
286 avalue(val(node(t, h))) : NULL; 280 avalue(val(node(t, h))) : NULL;
@@ -289,34 +283,14 @@ Object *lua_hashget (Hash *t, Object *ref)
289 Object *r = lua_hashget(p, ref); 283 Object *r = lua_hashget(p, ref);
290 if (tag(r) != T_NIL) { count++; return r; } 284 if (tag(r) != T_NIL) { count++; return r; }
291 } 285 }
292 }
293 286
294 { /* check "parents" field */ 287 h = present(t, &godparent); /* assert(h >= 0); */
295 Hash *ps; 288 p = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ?
296 Object parents;
297 tag(&parents) = T_STRING;
298 svalue(&parents) = "parents";
299 h = present(t, &parents); /* assert(h >= 0); */
300 ps = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ?
301 avalue(val(node(t, h))) : NULL; 289 avalue(val(node(t, h))) : NULL;
302 if (ps != NULL) 290 if (p != NULL)
303 { 291 {
304 Hash *p; 292 Object *r = lua_hashget(p, ref);
305 Object index; 293 if (tag(r) != T_NIL) { count++; return r; }
306 tag(&index) = T_NUMBER;
307 nvalue(&index) = 1;
308 h = present(ps, &index);
309 p = tag(ref(node(ps, h))) != T_NIL && tag(val(node(ps, h))) == T_ARRAY ?
310 avalue(val(node(ps, h))) : NULL;
311 while (p != NULL)
312 {
313 Object *r = lua_hashget(p, ref);
314 if (tag(r) != T_NIL) { count++; return r; }
315 nvalue(&index)++;
316 h = present(ps, &index);
317 p = tag(ref(node(ps, h))) != T_NIL && tag(val(node(ps, h))) == T_ARRAY ?
318 avalue(val(node(ps, h))) : NULL;
319 }
320 } 294 }
321 } 295 }
322 count++; 296 count++;
@@ -338,7 +312,7 @@ Object *lua_hashdefine (Hash *t, Object *ref)
338 if (tag(ref(n)) == T_NIL) 312 if (tag(ref(n)) == T_NIL)
339 { 313 {
340 nuse(t)++; 314 nuse(t)++;
341 if (nuse(t) > nhash(t)*REHASH_LIMIT) 315 if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT)
342 { 316 {
343 rehash(t); 317 rehash(t);
344 h = present(t, ref); 318 h = present(t, ref);