aboutsummaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c120
1 files changed, 96 insertions, 24 deletions
diff --git a/hash.c b/hash.c
index 1704acfe..549338a1 100644
--- a/hash.c
+++ b/hash.c
@@ -4,7 +4,7 @@
4** Luiz Henrique de Figueiredo - 17 Aug 90 4** Luiz Henrique de Figueiredo - 17 Aug 90
5*/ 5*/
6 6
7char *rcs_hash="$Id: hash.c,v 1.1 1993/12/17 18:41:19 celes Exp celes $"; 7char *rcs_hash="$Id: hash.c,v 1.2 1994/03/28 15:14:02 celes Exp celes $";
8 8
9#include <string.h> 9#include <string.h>
10#include <stdlib.h> 10#include <stdlib.h>
@@ -26,10 +26,23 @@ char *rcs_hash="$Id: hash.c,v 1.1 1993/12/17 18:41:19 celes Exp celes $";
26#define nhash(t) ((t)->nhash) 26#define nhash(t) ((t)->nhash)
27#define nodelist(t) ((t)->list) 27#define nodelist(t) ((t)->list)
28#define list(t,i) ((t)->list[i]) 28#define list(t,i) ((t)->list[i])
29#define markarray(t) ((t)->mark)
29#define ref_tag(n) (tag(&(n)->ref)) 30#define ref_tag(n) (tag(&(n)->ref))
30#define ref_nvalue(n) (nvalue(&(n)->ref)) 31#define ref_nvalue(n) (nvalue(&(n)->ref))
31#define ref_svalue(n) (svalue(&(n)->ref)) 32#define ref_svalue(n) (svalue(&(n)->ref))
32 33
34#ifndef ARRAYBLOCK
35#define ARRAYBLOCK 50
36#endif
37
38typedef struct ArrayList
39{
40 Hash *array;
41 struct ArrayList *next;
42} ArrayList;
43
44static ArrayList *listhead = NULL;
45
33static int head (Hash *t, Object *ref) /* hash function */ 46static int head (Hash *t, Object *ref) /* hash function */
34{ 47{
35 if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t)); 48 if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t));
@@ -91,7 +104,7 @@ static void freelist (Node *n)
91/* 104/*
92** Create a new hash. Return the hash pointer or NULL on error. 105** Create a new hash. Return the hash pointer or NULL on error.
93*/ 106*/
94Hash *lua_hashcreate (unsigned int nhash) 107static Hash *hashcreate (unsigned int nhash)
95{ 108{
96 Hash *t = new (Hash); 109 Hash *t = new (Hash);
97 if (t == NULL) 110 if (t == NULL)
@@ -113,7 +126,7 @@ Hash *lua_hashcreate (unsigned int nhash)
113/* 126/*
114** Delete a hash 127** Delete a hash
115*/ 128*/
116void lua_hashdelete (Hash *h) 129static void hashdelete (Hash *h)
117{ 130{
118 int i; 131 int i;
119 for (i=0; i<nhash(h); i++) 132 for (i=0; i<nhash(h); i++)
@@ -122,6 +135,86 @@ void lua_hashdelete (Hash *h)
122 free(h); 135 free(h);
123} 136}
124 137
138
139/*
140** Mark a hash and check its elements
141*/
142void lua_hashmark (Hash *h)
143{
144 if (markarray(h) == 0)
145 {
146 int i;
147 markarray(h) = 1;
148 for (i=0; i<nhash(h); i++)
149 {
150 Node *n;
151 for (n = list(h,i); n != NULL; n = n->next)
152 {
153 lua_markobject(&n->ref);
154 lua_markobject(&n->val);
155 }
156 }
157 }
158}
159
160/*
161** Garbage collection to arrays
162** Delete all unmarked arrays.
163*/
164void lua_hashcollector (void)
165{
166 ArrayList *curr = listhead, *prev = NULL;
167 while (curr != NULL)
168 {
169 ArrayList *next = curr->next;
170 if (markarray(curr->array) != 1)
171 {
172 if (prev == NULL) listhead = next;
173 else prev->next = next;
174 hashdelete(curr->array);
175 free(curr);
176 }
177 else
178 {
179 markarray(curr->array) = 0;
180 prev = curr;
181 }
182 curr = next;
183 }
184}
185
186
187/*
188** Create a new array
189** This function insert the new array at array list. It also
190** execute garbage collection if the number of array created
191** exceed a pre-defined range.
192*/
193Hash *lua_createarray (int nhash)
194{
195 ArrayList *new = new(ArrayList);
196 if (new == NULL)
197 {
198 lua_error ("not enough memory");
199 return NULL;
200 }
201 new->array = hashcreate(nhash);
202 if (new->array == NULL)
203 {
204 lua_error ("not enough memory");
205 return NULL;
206 }
207
208 if (lua_nentity == lua_block)
209 lua_pack();
210
211 lua_nentity++;
212 new->next = listhead;
213 listhead = new;
214 return new->array;
215}
216
217
125/* 218/*
126** If the hash node is present, return its pointer, otherwise create a new 219** If the hash node is present, return its pointer, otherwise create a new
127** node for the given reference and also return its pointer. 220** node for the given reference and also return its pointer.
@@ -151,26 +244,6 @@ Object *lua_hashdefine (Hash *t, Object *ref)
151 return (&n->val); 244 return (&n->val);
152} 245}
153 246
154/*
155** Mark a hash and check its elements
156*/
157void lua_hashmark (Hash *h)
158{
159 int i;
160
161 markarray(h) = 1;
162
163 for (i=0; i<nhash(h); i++)
164 {
165 Node *n;
166 for (n = list(h,i); n != NULL; n = n->next)
167 {
168 lua_markobject (&n->ref);
169 lua_markobject (&n->val);
170 }
171 }
172}
173
174 247
175/* 248/*
176** Internal function to manipulate arrays. 249** Internal function to manipulate arrays.
@@ -178,7 +251,6 @@ void lua_hashmark (Hash *h)
178** in the hash. 251** in the hash.
179** This function pushs the element value and its reference to the stack. 252** This function pushs the element value and its reference to the stack.
180*/ 253*/
181#include "lua.h"
182static void firstnode (Hash *a, int h) 254static void firstnode (Hash *a, int h)
183{ 255{
184 if (h < nhash(a)) 256 if (h < nhash(a))