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; |
