diff options
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.31 1999/12/14 18:42:57 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.32 2000/03/03 14:58:26 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 | */ |
@@ -46,8 +46,9 @@ void luaS_freeall (lua_State *L) { | |||
46 | 46 | ||
47 | static unsigned long hash_s (const char *s, long l) { | 47 | static unsigned long hash_s (const char *s, long l) { |
48 | unsigned long h = l; /* seed */ | 48 | unsigned long h = l; /* seed */ |
49 | while (l--) | 49 | long step = (l>>6)+1; /* if string is too long, don't hash all its chars */ |
50 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++)); | 50 | for (; l>0; l-=step) |
51 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++)); | ||
51 | return h; | 52 | return h; |
52 | } | 53 | } |
53 | 54 | ||
@@ -120,7 +121,8 @@ static void newentry (lua_State *L, stringtable *tb, TaggedString *ts, int h) { | |||
120 | 121 | ||
121 | TaggedString *luaS_newlstr (lua_State *L, const char *str, long l) { | 122 | TaggedString *luaS_newlstr (lua_State *L, const char *str, long l) { |
122 | unsigned long h = hash_s(str, l); | 123 | unsigned long h = hash_s(str, l); |
123 | stringtable *tb = &L->string_root[h%NUM_HASHSTR]; | 124 | stringtable *tb = &L->string_root[(l==0) ? 0 : |
125 | ((unsigned int)(str[0]+str[l-1]))&(NUM_HASHSTR-1)]; | ||
124 | int h1 = h&(tb->size-1); | 126 | int h1 = h&(tb->size-1); |
125 | TaggedString *ts; | 127 | TaggedString *ts; |
126 | for (ts = tb->hash[h1]; ts; ts = ts->nexthash) { | 128 | for (ts = tb->hash[h1]; ts; ts = ts->nexthash) { |
@@ -134,6 +136,10 @@ TaggedString *luaS_newlstr (lua_State *L, const char *str, long l) { | |||
134 | } | 136 | } |
135 | 137 | ||
136 | 138 | ||
139 | /* | ||
140 | ** uses '%' for one hashing with userdata because addresses are too regular, | ||
141 | ** so two '&' operations would be highly correlated | ||
142 | */ | ||
137 | TaggedString *luaS_createudata (lua_State *L, void *udata, int tag) { | 143 | TaggedString *luaS_createudata (lua_State *L, void *udata, int tag) { |
138 | unsigned long h = IntPoint(L, udata); | 144 | unsigned long h = IntPoint(L, udata); |
139 | stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; | 145 | stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; |