diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-08 14:28:48 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-08 14:28:48 -0200 |
commit | 7bdbd833b550bc4b7e6a5c1618845fce567c6af4 (patch) | |
tree | 6529c2857ff50380c439160520ec71eb93e107ed | |
parent | b22baf386d40aba5e11bd66f4c69acdf0e9219a1 (diff) | |
download | lua-7bdbd833b550bc4b7e6a5c1618845fce567c6af4.tar.gz lua-7bdbd833b550bc4b7e6a5c1618845fce567c6af4.tar.bz2 lua-7bdbd833b550bc4b7e6a5c1618845fce567c6af4.zip |
userdata and strings are kept in separate stringtables
-rw-r--r-- | lstring.c | 33 |
1 files changed, 17 insertions, 16 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.16 1999/01/04 13:37:29 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.17 1999/01/25 17:38:04 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,7 +14,9 @@ | |||
14 | #include "lua.h" | 14 | #include "lua.h" |
15 | 15 | ||
16 | 16 | ||
17 | #define NUM_HASHS 61 | 17 | #define NUM_HASHSTR 31 |
18 | #define NUM_HASHUDATA 31 | ||
19 | #define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA) | ||
18 | 20 | ||
19 | 21 | ||
20 | #define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ | 22 | #define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ |
@@ -121,10 +123,8 @@ static TaggedString *insert_s (char *str, long l, stringtable *tb) { | |||
121 | while ((ts = tb->hash[h1]) != NULL) { | 123 | while ((ts = tb->hash[h1]) != NULL) { |
122 | if (ts == &EMPTY) | 124 | if (ts == &EMPTY) |
123 | j = h1; | 125 | j = h1; |
124 | else if (ts->constindex >= 0 && | 126 | else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) |
125 | ts->u.s.len == l && | 127 | return ts; |
126 | (memcmp(str, ts->str, l) == 0)) | ||
127 | return ts; | ||
128 | h1 += (h&(size-2)) + 1; /* double hashing */ | 128 | h1 += (h&(size-2)) + 1; /* double hashing */ |
129 | if (h1 >= size) h1 -= size; | 129 | if (h1 >= size) h1 -= size; |
130 | } | 130 | } |
@@ -137,6 +137,7 @@ static TaggedString *insert_s (char *str, long l, stringtable *tb) { | |||
137 | return ts; | 137 | return ts; |
138 | } | 138 | } |
139 | 139 | ||
140 | |||
140 | static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | 141 | static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { |
141 | TaggedString *ts; | 142 | TaggedString *ts; |
142 | unsigned long h = (unsigned long)buff; | 143 | unsigned long h = (unsigned long)buff; |
@@ -151,10 +152,8 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | |||
151 | while ((ts = tb->hash[h1]) != NULL) { | 152 | while ((ts = tb->hash[h1]) != NULL) { |
152 | if (ts == &EMPTY) | 153 | if (ts == &EMPTY) |
153 | j = h1; | 154 | j = h1; |
154 | else if (ts->constindex < 0 && /* is a udata? */ | 155 | else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) |
155 | (tag == ts->u.d.tag || tag == LUA_ANYTAG) && | 156 | return ts; |
156 | buff == ts->u.d.v) | ||
157 | return ts; | ||
158 | h1 += (h&(size-2)) + 1; /* double hashing */ | 157 | h1 += (h&(size-2)) + 1; /* double hashing */ |
159 | if (h1 >= size) h1 -= size; | 158 | if (h1 >= size) h1 -= size; |
160 | } | 159 | } |
@@ -169,12 +168,13 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | |||
169 | 168 | ||
170 | 169 | ||
171 | TaggedString *luaS_createudata (void *udata, int tag) { | 170 | TaggedString *luaS_createudata (void *udata, int tag) { |
172 | return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); | 171 | int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR; |
172 | return insert_u(udata, tag, &L->string_root[t]); | ||
173 | } | 173 | } |
174 | 174 | ||
175 | TaggedString *luaS_newlstr (char *str, long l) { | 175 | TaggedString *luaS_newlstr (char *str, long l) { |
176 | int i = (l==0)?0:(unsigned char)str[0]; | 176 | int t = (l==0) ? 0 : ((unsigned char)str[0]*l)%NUM_HASHSTR; |
177 | return insert_s(str, l, &L->string_root[i%NUM_HASHS]); | 177 | return insert_s(str, l, &L->string_root[t]); |
178 | } | 178 | } |
179 | 179 | ||
180 | TaggedString *luaS_new (char *str) { | 180 | TaggedString *luaS_new (char *str) { |
@@ -240,13 +240,14 @@ TaggedString *luaS_collectudata (void) { | |||
240 | TaggedString *frees = NULL; | 240 | TaggedString *frees = NULL; |
241 | int i; | 241 | int i; |
242 | L->rootglobal.next = NULL; /* empty list of globals */ | 242 | L->rootglobal.next = NULL; /* empty list of globals */ |
243 | for (i=0; i<NUM_HASHS; i++) { | 243 | for (i=NUM_HASHSTR; i<NUM_HASHS; i++) { |
244 | stringtable *tb = &L->string_root[i]; | 244 | stringtable *tb = &L->string_root[i]; |
245 | int j; | 245 | int j; |
246 | for (j=0; j<tb->size; j++) { | 246 | for (j=0; j<tb->size; j++) { |
247 | TaggedString *t = tb->hash[j]; | 247 | TaggedString *t = tb->hash[j]; |
248 | if (t == NULL || t == &EMPTY || t->constindex != -1) | 248 | if (t == NULL || t == &EMPTY) |
249 | continue; /* get only user data */ | 249 | continue; |
250 | LUA_ASSERT(t->constindex == -1, "must be userdata"); | ||
250 | t->head.next = (GCnode *)frees; | 251 | t->head.next = (GCnode *)frees; |
251 | frees = t; | 252 | frees = t; |
252 | tb->hash[j] = &EMPTY; | 253 | tb->hash[j] = &EMPTY; |