[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: void lua_resizetable
- From: "Thomas Harning Jr." <harningt@...>
- Date: Tue, 24 Mar 2009 21:33:17 -0400
On Tue, Mar 24, 2009 at 9:16 PM, Sean Riley <sean@metaplace.com> wrote:
> Hello,
>
> I have a situation where I am storing potentially 1000’s of lua tables that
> I need to reference quickly from C. One optimal way of doing this seemed to
> be to put them into the array portion of the global table, that way I can
> use LUA_GLOBALSINDEX to easily get at those tables by a single integer
> lookup. But… the global table doesn’t seem to have an array – just a hash
> table, and adding to it with rawseti even with an integer index just puts
> the new values in the hash table.
>
> I couldn’t find a way to force the global table to have an array, so I made
> this function that lives in lapi.c:
>
> LUA_API void lua_resizetable (lua_State *L, int idx, int n) {
>
> StkId o;
>
> lua_lock(L);
>
> api_checknelems(L, 1);
>
> o = index2adr(L, idx);
>
> api_check(L, ttistable(o));
>
> luaH_resizearray(L, hvalue(o), n);
>
> luaC_barriert(L, hvalue(o), L->top-1);
>
> L->top--;
>
> lua_unlock(L);
>
> }
>
> So I can then call:
>
> lua_resizetable(ec.L, LUA_GLOBALSINDEX, 10000);
>
> Now the global table has an array and I can use rawseti and rawgeti to
> access my tables in linear time with code like:
>
> lua_rawgeti(ec.L, LUA_GLOBALSINDEX, m_value);
>
> Sure, I could have used another non-global table, but then I would have to
> look that table up, push it on the stack at an appropriate index every time,
> instead of using LUA_GLOBALSINDEX which is always valid.
>
> Is this the wrong thing to do?
Interesting approach. You might want to look at using an environment
table if you can isolate your C functions to be registered at a
specific location (see the io library implementation in Lua for an
example of using/registering an environment table for use in C
functions).
Another possibility is to use the lua registry table to store your
tables. You can readily use luaL_reg(L, LUA_REGISTRYINDEX); to
safely get integer references to the index of your given tables.
Another option is to immediately populate the LUA_REGISTRYINDEX w/
1000 entries and be guaranteed that luaL_reg used by any other code
won't take up any spots inside your expected space.
--
Thomas Harning Jr.