diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-03-28 15:28:25 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-03-28 15:28:25 -0300 |
commit | cfbe2333a443447396c6f610d4cc532c8564bde6 (patch) | |
tree | 65b3fa37d2c85932d17683bb1bca3956f2473a73 /lstring.c | |
parent | afc3fcf952aa9c09732edcc1f7c39d081e1cc909 (diff) | |
download | lua-cfbe2333a443447396c6f610d4cc532c8564bde6.tar.gz lua-cfbe2333a443447396c6f610d4cc532c8564bde6.tar.bz2 lua-cfbe2333a443447396c6f610d4cc532c8564bde6.zip |
string hash may not use all bytes (but this is configurable now) +
small other changes
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 33 |
1 files changed, 28 insertions, 5 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.21 2012/01/25 21:05:40 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.22 2012/02/01 21:57:15 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 | */ |
@@ -19,12 +19,34 @@ | |||
19 | 19 | ||
20 | 20 | ||
21 | /* | 21 | /* |
22 | ** maximum length for short strings, that is, strings that are | ||
23 | ** internalized. (Cannot be smaller than reserved words or tags | ||
24 | ** for metamethods, as these strings must be internalized; | ||
25 | ** #("function") = 8, #("__newindex") = 10.) | ||
26 | */ | ||
27 | #if !defined(LUAI_MAXSHORTLEN) | ||
28 | #define LUAI_MAXSHORTLEN 40 | ||
29 | #endif | ||
30 | |||
31 | |||
32 | /* | ||
33 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to | ||
34 | ** compute its hash | ||
35 | */ | ||
36 | #if !defined(LUAI_HASHLIMIT) | ||
37 | #define LUAI_HASHLIMIT 5 | ||
38 | #endif | ||
39 | |||
40 | |||
41 | /* | ||
22 | ** equality for long strings | 42 | ** equality for long strings |
23 | */ | 43 | */ |
24 | int luaS_eqlngstr (TString *a, TString *b) { | 44 | int luaS_eqlngstr (TString *a, TString *b) { |
25 | size_t len = a->tsv.len; | 45 | size_t len = a->tsv.len; |
26 | lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); | 46 | lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); |
27 | return (len == b->tsv.len) && (memcmp(getstr(a), getstr(b), len) == 0); | 47 | return (a == b) || /* same instance or... */ |
48 | ((len == b->tsv.len) && /* equal length and ... */ | ||
49 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ | ||
28 | } | 50 | } |
29 | 51 | ||
30 | 52 | ||
@@ -40,8 +62,9 @@ int luaS_eqstr (TString *a, TString *b) { | |||
40 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { | 62 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
41 | unsigned int h = seed ^ l; | 63 | unsigned int h = seed ^ l; |
42 | size_t l1; | 64 | size_t l1; |
43 | for (l1 = 0; l1 < l; l1++) | 65 | size_t step = (l >> LUAI_HASHLIMIT) + 1; |
44 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1])); | 66 | for (l1 = l; l1 >= step; l1 -= step) |
67 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); | ||
45 | return h; | 68 | return h; |
46 | } | 69 | } |
47 | 70 | ||
@@ -142,7 +165,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
142 | ** new string (with explicit length) | 165 | ** new string (with explicit length) |
143 | */ | 166 | */ |
144 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | 167 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { |
145 | if (l <= LUA_MAXSHORTLEN) /* short string? */ | 168 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ |
146 | return internshrstr(L, str, l); | 169 | return internshrstr(L, str, l); |
147 | else { | 170 | else { |
148 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) | 171 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) |