diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 12:16:35 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 12:16:35 -0200 |
commit | ac390020e91e14f00200ad3df97682b715d3e59b (patch) | |
tree | e86c7128814f6c754e9bebf4bbdad08ba4e8aeff | |
parent | 9b45439860879dd282e6d0896c4ee8102febc7fd (diff) | |
download | lua-ac390020e91e14f00200ad3df97682b715d3e59b.tar.gz lua-ac390020e91e14f00200ad3df97682b715d3e59b.tar.bz2 lua-ac390020e91e14f00200ad3df97682b715d3e59b.zip |
optimizations based on all types but number and nil are pointers
-rw-r--r-- | lobject.c | 13 | ||||
-rw-r--r-- | ltable.c | 114 | ||||
-rw-r--r-- | ltable.h | 11 |
3 files changed, 47 insertions, 91 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 1.60 2001/01/24 15:45:33 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.61 2001/01/25 16:45:36 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,15 +37,10 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) { | |||
37 | switch (ttype(t1)) { | 37 | switch (ttype(t1)) { |
38 | case LUA_TNUMBER: | 38 | case LUA_TNUMBER: |
39 | return nvalue(t1) == nvalue(t2); | 39 | return nvalue(t1) == nvalue(t2); |
40 | case LUA_TSTRING: case LUA_TUSERDATA: | 40 | case LUA_TNIL: |
41 | return 1; | ||
42 | default: /* all other types are equal if pointers are equal */ | ||
41 | return tsvalue(t1) == tsvalue(t2); | 43 | return tsvalue(t1) == tsvalue(t2); |
42 | case LUA_TTABLE: | ||
43 | return hvalue(t1) == hvalue(t2); | ||
44 | case LUA_TFUNCTION: | ||
45 | return clvalue(t1) == clvalue(t2); | ||
46 | default: | ||
47 | lua_assert(ttype(t1) == LUA_TNIL); | ||
48 | return 1; /* LUA_TNIL */ | ||
49 | } | 44 | } |
50 | } | 45 | } |
51 | 46 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.68 2001/01/26 13:18:00 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -31,8 +31,9 @@ | |||
31 | #define TagDefault LUA_TTABLE | 31 | #define TagDefault LUA_TTABLE |
32 | 32 | ||
33 | 33 | ||
34 | #define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)]) | 34 | #define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)]) |
35 | #define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)]) | 35 | #define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)]) |
36 | #define hashpointer(t,p) (&t->node[IntPoint(p)&(t->size-1)]) | ||
36 | 37 | ||
37 | 38 | ||
38 | /* | 39 | /* |
@@ -40,73 +41,18 @@ | |||
40 | ** of its hash value) | 41 | ** of its hash value) |
41 | */ | 42 | */ |
42 | Node *luaH_mainposition (const Hash *t, const TObject *key) { | 43 | Node *luaH_mainposition (const Hash *t, const TObject *key) { |
43 | luint32 h; | ||
44 | switch (ttype(key)) { | 44 | switch (ttype(key)) { |
45 | case LUA_TNUMBER: | 45 | case LUA_TNUMBER: |
46 | return hashnum(t, nvalue(key)); | 46 | return hashnum(t, nvalue(key)); |
47 | case LUA_TSTRING: | 47 | case LUA_TSTRING: |
48 | return hashstr(t, tsvalue(key)); | 48 | return hashstr(t, tsvalue(key)); |
49 | case LUA_TUSERDATA: | 49 | default: /* all other types are hashed as (void *) */ |
50 | h = IntPoint(tsvalue(key)); | 50 | return hashpointer(t, hvalue(key)); |
51 | break; | ||
52 | case LUA_TTABLE: | ||
53 | h = IntPoint(hvalue(key)); | ||
54 | break; | ||
55 | case LUA_TFUNCTION: | ||
56 | h = IntPoint(clvalue(key)); | ||
57 | break; | ||
58 | default: | ||
59 | return NULL; /* invalid key */ | ||
60 | } | 51 | } |
61 | return &t->node[h&(t->size-1)]; | ||
62 | } | 52 | } |
63 | 53 | ||
64 | 54 | ||
65 | static const TObject *luaH_getany (const Hash *t, const TObject *key) { | 55 | Node *luaH_next (lua_State *L, Hash *t, const TObject *key) { |
66 | Node *n = luaH_mainposition(t, key); | ||
67 | while (n) { | ||
68 | if (luaO_equalObj(key, &n->key)) | ||
69 | return &n->val; | ||
70 | n = n->next; | ||
71 | } | ||
72 | return &luaO_nilobject; /* key not found */ | ||
73 | } | ||
74 | |||
75 | |||
76 | /* specialized version for numbers */ | ||
77 | const TObject *luaH_getnum (const Hash *t, lua_Number key) { | ||
78 | Node *n = hashnum(t, key); | ||
79 | do { | ||
80 | if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER) | ||
81 | return &n->val; | ||
82 | n = n->next; | ||
83 | } while (n); | ||
84 | return &luaO_nilobject; /* key not found */ | ||
85 | } | ||
86 | |||
87 | |||
88 | /* specialized version for strings */ | ||
89 | const TObject *luaH_getstr (const Hash *t, TString *key) { | ||
90 | Node *n = hashstr(t, key); | ||
91 | do { | ||
92 | if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING) | ||
93 | return &n->val; | ||
94 | n = n->next; | ||
95 | } while (n); | ||
96 | return &luaO_nilobject; /* key not found */ | ||
97 | } | ||
98 | |||
99 | |||
100 | const TObject *luaH_get (const Hash *t, const TObject *key) { | ||
101 | switch (ttype(key)) { | ||
102 | case LUA_TNUMBER: return luaH_getnum(t, nvalue(key)); | ||
103 | case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); | ||
104 | default: return luaH_getany(t, key); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | |||
109 | Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { | ||
110 | int i; | 56 | int i; |
111 | if (ttype(key) == LUA_TNIL) | 57 | if (ttype(key) == LUA_TNIL) |
112 | i = 0; /* first iteration */ | 58 | i = 0; /* first iteration */ |
@@ -197,8 +143,8 @@ static void rehash (lua_State *L, Hash *t) { | |||
197 | 143 | ||
198 | /* | 144 | /* |
199 | ** inserts a new key into a hash table; first, check whether key's main | 145 | ** inserts a new key into a hash table; first, check whether key's main |
200 | ** position is free; if not, check whether colliding node is in its main | 146 | ** position is free. If not, check whether colliding node is in its main |
201 | ** position or not; if it is not, move colliding node to an empty place and | 147 | ** position or not: if it is not, move colliding node to an empty place and |
202 | ** put new key in its main position; otherwise (colliding node is in its main | 148 | ** put new key in its main position; otherwise (colliding node is in its main |
203 | ** position), new key goes to an empty position. | 149 | ** position), new key goes to an empty position. |
204 | */ | 150 | */ |
@@ -234,20 +180,9 @@ static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { | |||
234 | } | 180 | } |
235 | 181 | ||
236 | 182 | ||
237 | static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) { | 183 | /* |
238 | Node *mp = luaH_mainposition(t, key); | 184 | ** search function for numbers |
239 | Node *n = mp; | 185 | */ |
240 | if (!mp) | ||
241 | luaD_error(L, "table index is nil"); | ||
242 | do { /* check whether `key' is somewhere in the chain */ | ||
243 | if (luaO_equalObj(key, &n->key)) | ||
244 | return &n->val; /* that's all */ | ||
245 | else n = n->next; | ||
246 | } while (n); | ||
247 | return newkey(L, t, mp, key); /* `key' not found; must insert it */ | ||
248 | } | ||
249 | |||
250 | |||
251 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { | 186 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { |
252 | TObject kobj; | 187 | TObject kobj; |
253 | Node *mp = hashnum(t, key); | 188 | Node *mp = hashnum(t, key); |
@@ -257,12 +192,16 @@ TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { | |||
257 | return &n->val; /* that's all */ | 192 | return &n->val; /* that's all */ |
258 | else n = n->next; | 193 | else n = n->next; |
259 | } while (n); | 194 | } while (n); |
195 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
260 | /* `key' not found; must insert it */ | 196 | /* `key' not found; must insert it */ |
261 | setnvalue(&kobj, key); | 197 | setnvalue(&kobj, key); |
262 | return newkey(L, t, mp, &kobj); | 198 | return newkey(L, t, mp, &kobj); |
263 | } | 199 | } |
264 | 200 | ||
265 | 201 | ||
202 | /* | ||
203 | ** search function for strings | ||
204 | */ | ||
266 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { | 205 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { |
267 | TObject kobj; | 206 | TObject kobj; |
268 | Node *mp = hashstr(t, key); | 207 | Node *mp = hashstr(t, key); |
@@ -272,16 +211,37 @@ TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { | |||
272 | return &n->val; /* that's all */ | 211 | return &n->val; /* that's all */ |
273 | else n = n->next; | 212 | else n = n->next; |
274 | } while (n); | 213 | } while (n); |
214 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
275 | /* `key' not found; must insert it */ | 215 | /* `key' not found; must insert it */ |
276 | setsvalue(&kobj, key); | 216 | setsvalue(&kobj, key); |
277 | return newkey(L, t, mp, &kobj); | 217 | return newkey(L, t, mp, &kobj); |
278 | } | 218 | } |
279 | 219 | ||
280 | 220 | ||
221 | /* | ||
222 | ** search function for 'pointer' types | ||
223 | */ | ||
224 | static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) { | ||
225 | Node *mp = hashpointer(t, hvalue(key)); | ||
226 | Node *n = mp; | ||
227 | do { /* check whether `key' is somewhere in the chain */ | ||
228 | /* compare as `hvalue', but may be other pointers (it is the same) */ | ||
229 | if (hvalue(&n->key) == hvalue(key) && ttype(&n->key) == ttype(key)) | ||
230 | return &n->val; /* that's all */ | ||
231 | else n = n->next; | ||
232 | } while (n); | ||
233 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
234 | return newkey(L, t, mp, key); /* `key' not found; must insert it */ | ||
235 | } | ||
236 | |||
237 | |||
281 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { | 238 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { |
282 | switch (ttype(key)) { | 239 | switch (ttype(key)) { |
283 | case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key)); | 240 | case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key)); |
284 | case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key)); | 241 | case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key)); |
242 | case LUA_TNIL: | ||
243 | if (L) luaD_error(L, "table index is nil"); | ||
244 | return (TObject *)&luaO_nilobject; /* get option */ | ||
285 | default: return luaH_setany(L, t, key); | 245 | default: return luaH_setany(L, t, key); |
286 | } | 246 | } |
287 | } | 247 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 1.28 2001/01/26 13:18:00 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,13 +14,14 @@ | |||
14 | #define key(n) (&(n)->key) | 14 | #define key(n) (&(n)->key) |
15 | #define val(n) (&(n)->val) | 15 | #define val(n) (&(n)->val) |
16 | 16 | ||
17 | #define luaH_get(t,k) luaH_set(NULL,t,k) | ||
18 | #define luaH_getnum(t,k) luaH_setnum(NULL,t,k) | ||
19 | #define luaH_getstr(t,k) luaH_setstr(NULL,t,k) | ||
20 | |||
17 | Hash *luaH_new (lua_State *L, int nhash); | 21 | Hash *luaH_new (lua_State *L, int nhash); |
18 | void luaH_free (lua_State *L, Hash *t); | 22 | void luaH_free (lua_State *L, Hash *t); |
19 | const TObject *luaH_get (const Hash *t, const TObject *key); | ||
20 | const TObject *luaH_getnum (const Hash *t, lua_Number key); | ||
21 | const TObject *luaH_getstr (const Hash *t, TString *key); | ||
22 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); | 23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); |
23 | Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); | 24 | Node * luaH_next (lua_State *L, Hash *t, const TObject *r); |
24 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); | 25 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); |
25 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); | 26 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); |
26 | 27 | ||