diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-06-02 16:06:14 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-06-02 16:06:14 -0300 |
commit | b8691f13a8e3e9bb7fbd91d1f099eb517a9d5b35 (patch) | |
tree | f3375e6a5c13c92e58a257aff7c7672c2c149dc0 | |
parent | f4718544de97bd2fc22117424ba0736c5295a8f2 (diff) | |
download | lua-b8691f13a8e3e9bb7fbd91d1f099eb517a9d5b35.tar.gz lua-b8691f13a8e3e9bb7fbd91d1f099eb517a9d5b35.tar.bz2 lua-b8691f13a8e3e9bb7fbd91d1f099eb517a9d5b35.zip |
`getn' uses binary search if it has to count elements
-rw-r--r-- | lauxlib.c | 35 |
1 files changed, 27 insertions, 8 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.113 2004/05/31 19:27:14 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.114 2004/06/02 13:50:46 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -299,6 +299,31 @@ LUALIB_API void luaL_setn (lua_State *L, int t, int n) { | |||
299 | } | 299 | } |
300 | 300 | ||
301 | 301 | ||
302 | /* find an `n' such that t[n] ~= nil and t[n+1] == nil */ | ||
303 | static int countn (lua_State *L, int t) { | ||
304 | int i = LUA_FIRSTINDEX - 1; | ||
305 | int j = 2; | ||
306 | /* find `i' such that i <= n < i*2 (= j) */ | ||
307 | for (;;) { | ||
308 | lua_rawgeti(L, t, j); | ||
309 | if (lua_isnil(L, -1)) break; | ||
310 | lua_pop(L, 1); | ||
311 | i = j; | ||
312 | j = i*2; | ||
313 | } | ||
314 | lua_pop(L, 1); | ||
315 | /* i <= n < j; do a binary search */ | ||
316 | while (i < j-1) { | ||
317 | int m = (i+j)/2; | ||
318 | lua_rawgeti(L, t, m); | ||
319 | if (lua_isnil(L, -1)) j = m; | ||
320 | else i = m; | ||
321 | lua_pop(L, 1); | ||
322 | } | ||
323 | return i - LUA_FIRSTINDEX + 1; | ||
324 | } | ||
325 | |||
326 | |||
302 | LUALIB_API int luaL_getn (lua_State *L, int t) { | 327 | LUALIB_API int luaL_getn (lua_State *L, int t) { |
303 | int n; | 328 | int n; |
304 | t = abs_index(L, t); | 329 | t = abs_index(L, t); |
@@ -308,13 +333,7 @@ LUALIB_API int luaL_getn (lua_State *L, int t) { | |||
308 | if ((n = checkint(L, 2)) >= 0) return n; | 333 | if ((n = checkint(L, 2)) >= 0) return n; |
309 | lua_getfield(L, t, "n"); /* else try t.n */ | 334 | lua_getfield(L, t, "n"); /* else try t.n */ |
310 | if ((n = checkint(L, 1)) >= 0) return n; | 335 | if ((n = checkint(L, 1)) >= 0) return n; |
311 | for (n = LUA_FIRSTINDEX; ; n++) { /* else must count elements */ | 336 | return countn(L, t); |
312 | lua_rawgeti(L, t, n); | ||
313 | if (lua_isnil(L, -1)) break; | ||
314 | lua_pop(L, 1); | ||
315 | } | ||
316 | lua_pop(L, 1); | ||
317 | return n - LUA_FIRSTINDEX; | ||
318 | } | 337 | } |
319 | 338 | ||
320 | /* }====================================================== */ | 339 | /* }====================================================== */ |