diff options
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 | |||