aboutsummaryrefslogtreecommitdiff
path: root/lstring.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-04-29 14:09:41 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-04-29 14:09:41 -0300
commitea445708839d48f03d32817071e5fce1e08c3927 (patch)
tree7b2133e68875cd8b7b5657dcb5872bdd75782b3f /lstring.c
parente091a254dfe4521d837469d3ae7cc329e2df3376 (diff)
downloadlua-ea445708839d48f03d32817071e5fce1e08c3927.tar.gz
lua-ea445708839d48f03d32817071e5fce1e08c3927.tar.bz2
lua-ea445708839d48f03d32817071e5fce1e08c3927.zip
hash table for strings is rehashed in place
Diffstat (limited to 'lstring.c')
-rw-r--r--lstring.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/lstring.c b/lstring.c
index e4903127..281d35fd 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.11 2008/02/19 18:55:09 roberto Exp roberto $ 2** $Id: lstring.c,v 2.12 2009/04/17 14:40:13 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*/
@@ -20,30 +20,32 @@
20 20
21 21
22void luaS_resize (lua_State *L, int newsize) { 22void luaS_resize (lua_State *L, int newsize) {
23 GCObject **newhash;
24 stringtable *tb;
25 int i; 23 int i;
24 stringtable *tb = &G(L)->strt;
26 if (G(L)->gcstate == GCSsweepstring) 25 if (G(L)->gcstate == GCSsweepstring)
27 return; /* cannot resize during GC traverse */ 26 return; /* cannot resize during GC traverse */
28 newhash = luaM_newvector(L, newsize, GCObject *); 27 if (newsize > tb->size) {
29 tb = &G(L)->strt; 28 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
30 for (i=0; i<newsize; i++) newhash[i] = NULL; 29 for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
30 }
31 /* rehash */ 31 /* rehash */
32 for (i=0; i<tb->size; i++) { 32 for (i=0; i<tb->size; i++) {
33 GCObject *p = tb->hash[i]; 33 GCObject *p = tb->hash[i];
34 tb->hash[i] = NULL;
34 while (p) { /* for each node in the list */ 35 while (p) { /* for each node in the list */
35 GCObject *next = gch(p)->next; /* save next */ 36 GCObject *next = gch(p)->next; /* save next */
36 unsigned int h = gco2ts(p)->hash; 37 unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */
37 int h1 = lmod(h, newsize); /* new position */ 38 gch(p)->next = tb->hash[h]; /* chain it */
38 lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 39 tb->hash[h] = p;
39 gch(p)->next = newhash[h1]; /* chain it */
40 newhash[h1] = p;
41 p = next; 40 p = next;
42 } 41 }
43 } 42 }
44 luaM_freearray(L, tb->hash, tb->size); 43 if (newsize < tb->size) {
44 /* shrinking slice must be empty */
45 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
46 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
47 }
45 tb->size = newsize; 48 tb->size = newsize;
46 tb->hash = newhash;
47} 49}
48 50
49 51
@@ -84,12 +86,12 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
84 TString *ts = rawgco2ts(o); 86 TString *ts = rawgco2ts(o);
85 if (h == ts->tsv.hash && ts->tsv.len == l && 87 if (h == ts->tsv.hash && ts->tsv.len == l &&
86 (memcmp(str, getstr(ts), l) == 0)) { 88 (memcmp(str, getstr(ts), l) == 0)) {
87 /* string may be dead */ 89 if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */
88 if (isdead(G(L), o)) changewhite(o); 90 changewhite(o); /* resurrect it */
89 return ts; 91 return ts;
90 } 92 }
91 } 93 }
92 return newlstr(L, str, l, h); /* not found */ 94 return newlstr(L, str, l, h); /* not found; create a new string */
93} 95}
94 96
95 97