lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.