diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-10 15:41:50 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-10 15:41:50 -0200 |
| commit | 08496eea8b277d37c4de9cf75a011715ad6a4100 (patch) | |
| tree | 9c3eef538b85f79ece0a0993e4d99930be6f6039 /lstring.c | |
| parent | 4ff55457095728b95cc5dcdbab0bca7255bd5387 (diff) | |
| download | lua-08496eea8b277d37c4de9cf75a011715ad6a4100.tar.gz lua-08496eea8b277d37c4de9cf75a011715ad6a4100.tar.bz2 lua-08496eea8b277d37c4de9cf75a011715ad6a4100.zip | |
small changes in lstring
Diffstat (limited to 'lstring.c')
| -rw-r--r-- | lstring.c | 44 |
1 files changed, 14 insertions, 30 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.47 2000/12/22 16:57:46 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.48 2000/12/28 12:55:41 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 | */ |
| @@ -15,6 +15,8 @@ | |||
| 15 | #include "lstring.h" | 15 | #include "lstring.h" |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | #define lmod(s,size) ((int)((s) & ((size)-1))) | ||
| 19 | |||
| 18 | 20 | ||
| 19 | void luaS_init (lua_State *L) { | 21 | void luaS_init (lua_State *L) { |
| 20 | luaS_resize(L, &L->strt, MINPOWER2); | 22 | luaS_resize(L, &L->strt, MINPOWER2); |
| @@ -30,15 +32,6 @@ void luaS_freeall (lua_State *L) { | |||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | static luint32 hash_s (const char *s, size_t l) { | ||
| 34 | luint32 h = l; /* seed */ | ||
| 35 | size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */ | ||
| 36 | for (; l>=step; l-=step) | ||
| 37 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++)); | ||
| 38 | return h; | ||
| 39 | } | ||
| 40 | |||
| 41 | |||
| 42 | void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | 35 | void luaS_resize (lua_State *L, stringtable *tb, int newsize) { |
| 43 | TString **newhash = luaM_newvector(L, newsize, TString *); | 36 | TString **newhash = luaM_newvector(L, newsize, TString *); |
| 44 | int i; | 37 | int i; |
| @@ -49,8 +42,8 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
| 49 | while (p) { /* for each node in the list */ | 42 | while (p) { /* for each node in the list */ |
| 50 | TString *next = p->nexthash; /* save next */ | 43 | TString *next = p->nexthash; /* save next */ |
| 51 | luint32 h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value); | 44 | luint32 h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value); |
| 52 | int h1 = h&(newsize-1); /* new position */ | 45 | int h1 = lmod(h, newsize); /* new position */ |
| 53 | LUA_ASSERT(h%newsize == (h&(newsize-1)), | 46 | LUA_ASSERT(h%newsize == lmod(h, newsize), |
| 54 | "a&(x-1) == a%x, for x power of 2"); | 47 | "a&(x-1) == a%x, for x power of 2"); |
| 55 | p->nexthash = newhash[h1]; /* chain it in new position */ | 48 | p->nexthash = newhash[h1]; /* chain it in new position */ |
| 56 | newhash[h1] = p; | 49 | newhash[h1] = p; |
| @@ -74,10 +67,13 @@ static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { | |||
| 74 | 67 | ||
| 75 | 68 | ||
| 76 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | 69 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { |
| 77 | luint32 h = hash_s(str, l); | ||
| 78 | int h1 = h & (L->strt.size-1); | ||
| 79 | TString *ts; | 70 | TString *ts; |
| 80 | for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) { | 71 | luint32 h = l; /* seed */ |
| 72 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ | ||
| 73 | size_t l1; | ||
| 74 | for (l1=l; l1>=step; l1-=step) /* compute hash */ | ||
| 75 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)str[l1-1]); | ||
| 76 | for (ts = L->strt.hash[lmod(h, L->strt.size)]; ts; ts = ts->nexthash) { | ||
| 81 | if (ts->len == l && (memcmp(str, ts->str, l) == 0)) | 77 | if (ts->len == l && (memcmp(str, ts->str, l) == 0)) |
| 82 | return ts; | 78 | return ts; |
| 83 | } | 79 | } |
| @@ -90,7 +86,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 90 | ts->u.s.constindex = 0; | 86 | ts->u.s.constindex = 0; |
| 91 | memcpy(ts->str, str, l); | 87 | memcpy(ts->str, str, l); |
| 92 | ts->str[l] = 0; /* ending 0 */ | 88 | ts->str[l] = 0; /* ending 0 */ |
| 93 | newentry(L, &L->strt, ts, h1); /* insert it on table */ | 89 | newentry(L, &L->strt, ts, lmod(h, L->strt.size)); /* insert it on table */ |
| 94 | return ts; | 90 | return ts; |
| 95 | } | 91 | } |
| 96 | 92 | ||
| @@ -104,13 +100,13 @@ TString *luaS_newudata (lua_State *L, size_t s, void *udata) { | |||
| 104 | ts->u.d.tag = 0; | 100 | ts->u.d.tag = 0; |
| 105 | ts->u.d.value = (udata == NULL) ? uts+1 : udata; | 101 | ts->u.d.value = (udata == NULL) ? uts+1 : udata; |
| 106 | /* insert it on table */ | 102 | /* insert it on table */ |
| 107 | newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1)); | 103 | newentry(L, &L->udt, ts, lmod(IntPoint(ts->u.d.value), L->udt.size)); |
| 108 | return ts; | 104 | return ts; |
| 109 | } | 105 | } |
| 110 | 106 | ||
| 111 | 107 | ||
| 112 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { | 108 | TString *luaS_createudata (lua_State *L, void *udata, int tag) { |
| 113 | int h1 = IntPoint(udata) & (L->udt.size-1); | 109 | int h1 = lmod(IntPoint(udata), L->udt.size); |
| 114 | TString *ts; | 110 | TString *ts; |
| 115 | for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) { | 111 | for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) { |
| 116 | if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) | 112 | if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) |
| @@ -123,15 +119,3 @@ TString *luaS_createudata (lua_State *L, void *udata, int tag) { | |||
| 123 | return ts; | 119 | return ts; |
| 124 | } | 120 | } |
| 125 | 121 | ||
| 126 | |||
| 127 | TString *luaS_new (lua_State *L, const char *str) { | ||
| 128 | return luaS_newlstr(L, str, strlen(str)); | ||
| 129 | } | ||
| 130 | |||
| 131 | |||
| 132 | TString *luaS_newfixed (lua_State *L, const char *str) { | ||
| 133 | TString *ts = luaS_new(L, str); | ||
| 134 | if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */ | ||
| 135 | return ts; | ||
| 136 | } | ||
| 137 | |||
