diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-25 15:38:04 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-25 15:38:04 -0200 |
commit | 13ad46b67d8b5d4402215e07b412b8b786eb27ea (patch) | |
tree | d0b9ff329329ff3defc4895f628d44f59733b532 | |
parent | 1b45e967b4dcb234551c2a731147b111584f4145 (diff) | |
download | lua-13ad46b67d8b5d4402215e07b412b8b786eb27ea.tar.gz lua-13ad46b67d8b5d4402215e07b412b8b786eb27ea.tar.bz2 lua-13ad46b67d8b5d4402215e07b412b8b786eb27ea.zip |
uses the same double hashing that is used for tables
-rw-r--r-- | lstring.c | 29 |
1 files changed, 17 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.15 1998/08/10 21:36:32 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.16 1999/01/04 13:37:29 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 | */ |
@@ -51,8 +51,7 @@ static int newsize (stringtable *tb) { | |||
51 | for (i=0; i<size; i++) | 51 | for (i=0; i<size; i++) |
52 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) | 52 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) |
53 | realuse++; | 53 | realuse++; |
54 | return luaO_redimension((realuse+1)*2+6); /* +1 is the new element, +6 to | 54 | return luaO_redimension((realuse+1)*2); /* +1 is the new element */ |
55 | ensure minimum size of 8 (for double hashing) */ | ||
56 | } | 55 | } |
57 | 56 | ||
58 | 57 | ||
@@ -68,9 +67,10 @@ static void grow (stringtable *tb) { | |||
68 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { | 67 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { |
69 | unsigned long h = tb->hash[i]->hash; | 68 | unsigned long h = tb->hash[i]->hash; |
70 | int h1 = h%ns; | 69 | int h1 = h%ns; |
71 | int h2 = 8-(h&7); | 70 | while (newhash[h1]) { |
72 | while (newhash[h1]) | 71 | h1 += (h&(ns-2)) + 1; /* double hashing */ |
73 | h1 = (h1+h2)%ns; | 72 | if (h1 >= ns) h1 -= ns; |
73 | } | ||
74 | newhash[h1] = tb->hash[i]; | 74 | newhash[h1] = tb->hash[i]; |
75 | tb->nuse++; | 75 | tb->nuse++; |
76 | } | 76 | } |
@@ -113,18 +113,20 @@ static TaggedString *insert_s (char *str, long l, stringtable *tb) { | |||
113 | int size = tb->size; | 113 | int size = tb->size; |
114 | int j = -1; | 114 | int j = -1; |
115 | int h1; | 115 | int h1; |
116 | int h2 = 8-(h&7); /* for double hashing */ | ||
117 | if ((long)tb->nuse*3 >= (long)size*2) { | 116 | if ((long)tb->nuse*3 >= (long)size*2) { |
118 | grow(tb); | 117 | grow(tb); |
119 | size = tb->size; | 118 | size = tb->size; |
120 | } | 119 | } |
121 | for (h1 = h%size; (ts = tb->hash[h1]) != NULL; h1 = (h1+h2)%size) { | 120 | h1 = h%size; |
121 | while ((ts = tb->hash[h1]) != NULL) { | ||
122 | if (ts == &EMPTY) | 122 | if (ts == &EMPTY) |
123 | j = h1; | 123 | j = h1; |
124 | else if (ts->constindex >= 0 && | 124 | else if (ts->constindex >= 0 && |
125 | ts->u.s.len == l && | 125 | ts->u.s.len == l && |
126 | (memcmp(str, ts->str, l) == 0)) | 126 | (memcmp(str, ts->str, l) == 0)) |
127 | return ts; | 127 | return ts; |
128 | h1 += (h&(size-2)) + 1; /* double hashing */ | ||
129 | if (h1 >= size) h1 -= size; | ||
128 | } | 130 | } |
129 | /* not found */ | 131 | /* not found */ |
130 | if (j != -1) /* is there an EMPTY space? */ | 132 | if (j != -1) /* is there an EMPTY space? */ |
@@ -141,18 +143,20 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | |||
141 | int size = tb->size; | 143 | int size = tb->size; |
142 | int j = -1; | 144 | int j = -1; |
143 | int h1; | 145 | int h1; |
144 | int h2 = 8-(h&7); /* for double hashing */ | ||
145 | if ((long)tb->nuse*3 >= (long)size*2) { | 146 | if ((long)tb->nuse*3 >= (long)size*2) { |
146 | grow(tb); | 147 | grow(tb); |
147 | size = tb->size; | 148 | size = tb->size; |
148 | } | 149 | } |
149 | for (h1 = h%size; (ts = tb->hash[h1]) != NULL; h1 = (h1+h2)%size) { | 150 | h1 = h%size; |
151 | while ((ts = tb->hash[h1]) != NULL) { | ||
150 | if (ts == &EMPTY) | 152 | if (ts == &EMPTY) |
151 | j = h1; | 153 | j = h1; |
152 | else if (ts->constindex < 0 && /* is a udata? */ | 154 | else if (ts->constindex < 0 && /* is a udata? */ |
153 | (tag == ts->u.d.tag || tag == LUA_ANYTAG) && | 155 | (tag == ts->u.d.tag || tag == LUA_ANYTAG) && |
154 | buff == ts->u.d.v) | 156 | buff == ts->u.d.v) |
155 | return ts; | 157 | return ts; |
158 | h1 += (h&(size-2)) + 1; /* double hashing */ | ||
159 | if (h1 >= size) h1 -= size; | ||
156 | } | 160 | } |
157 | /* not found */ | 161 | /* not found */ |
158 | if (j != -1) /* is there an EMPTY space? */ | 162 | if (j != -1) /* is there an EMPTY space? */ |
@@ -163,6 +167,7 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | |||
163 | return ts; | 167 | return ts; |
164 | } | 168 | } |
165 | 169 | ||
170 | |||
166 | TaggedString *luaS_createudata (void *udata, int tag) { | 171 | TaggedString *luaS_createudata (void *udata, int tag) { |
167 | return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); | 172 | return insert_u(udata, tag, &L->string_root[(unsigned)udata%NUM_HASHS]); |
168 | } | 173 | } |