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