diff options
author | Waldemar Celes <celes@tecgraf.puc-rio.br> | 1994-10-11 09:59:49 -0300 |
---|---|---|
committer | Waldemar Celes <celes@tecgraf.puc-rio.br> | 1994-10-11 09:59:49 -0300 |
commit | d107d5bfd21afb490616cc8f082d965ff9fa9f58 (patch) | |
tree | b0803718e972897cc2e7207fdcf9dca0054c0a43 /hash.c | |
parent | d7d7b477bb4e09fc69e31ccf21106a2c07fa441d (diff) | |
download | lua-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.c | 118 |
1 files changed, 46 insertions, 72 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** hash manager for lua | 3 | ** hash manager for lua |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_hash="$Id: hash.c,v 2.6 1994/08/17 17:41:23 celes Exp celes $"; | 6 | char *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 | ||
36 | typedef struct ArrayList | 36 | static Hash *listhead = NULL; |
37 | { | ||
38 | Hash *array; | ||
39 | struct ArrayList *next; | ||
40 | } ArrayList; | ||
41 | |||
42 | static ArrayList *listhead = NULL; | ||
43 | 37 | ||
44 | 38 | ||
45 | 39 | ||
46 | /* hash dimensions values */ | 40 | /* hash dimensions values */ |
47 | static int dimensions[] = | 41 | static 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}; | ||
49 | static int redimension (int nhash) | 44 | static 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 | ||
87 | static 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 | |||
92 | static int present (Hash *t, Object *ref) | 98 | static 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 | */ |
188 | void lua_hashcollector (void) | 187 | void 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 | */ |
217 | Hash *lua_createarray (int nhash) | 215 | Hash *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); |