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)) |
