diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc index 46968c4b02c37df996fed2af841db4d66eff18c9..d25382c1b7842ebbed6e8d1c241dc06f428748ae 100644 --- a/src/box/lua/tuple.cc +++ b/src/box/lua/tuple.cc @@ -53,7 +53,6 @@ extern "C" { static const char *tuplelib_name = "box.tuple"; static const char *tuple_iteratorlib_name = "box.tuple.iterator"; -static int tuple_totable_mt_ref = 0; /* a precreated metable for totable() */ extern char tuple_lua[]; /* Lua source */ @@ -375,48 +374,6 @@ lbox_tuple_findall(struct lua_State *L) return lbox_tuple_find_do(L, true); } -static int -lbox_tuple_unpack(struct lua_State *L) -{ - int argc = lua_gettop(L); - (void) argc; - struct tuple *tuple = lua_checktuple(L, 1); - - struct tuple_iterator it; - tuple_rewind(&it, tuple); - const char *field; - while ((field = tuple_next(&it))) - luamp_decode(L, &field); - - assert(lua_gettop(L) == argc + tuple_arity(tuple)); - (void) argc; - return tuple_arity(tuple); -} - -static int -lbox_tuple_totable(struct lua_State *L) -{ - struct tuple *tuple = lua_checktuple(L, 1); - lua_newtable(L); - int index = 1; - - struct tuple_iterator it; - tuple_rewind(&it, tuple); - const char *field; - while ((field = tuple_next(&it))) { - lua_pushnumber(L, index++); - luamp_decode(L, &field); - lua_rawset(L, -3); - } - - /* Hint serializer */ - assert(tuple_totable_mt_ref != 0); - lua_rawgeti(L, LUA_REGISTRYINDEX, tuple_totable_mt_ref); - lua_setmetatable(L, -2); - - return 1; -} - void lbox_pushtuple(struct lua_State *L, struct tuple *tuple) { @@ -439,8 +396,6 @@ static const struct luaL_reg lbox_tuple_meta[] = { {"transform", lbox_tuple_transform}, {"find", lbox_tuple_find}, {"findall", lbox_tuple_findall}, - {"unpack", lbox_tuple_unpack}, - {"totable", lbox_tuple_totable}, {NULL, NULL} }; @@ -490,14 +445,6 @@ box_lua_tuple_init(struct lua_State *L) luamp_set_encode_extension(luamp_encode_extension_box); - /* Precreate a metatable for tuple_unpack */ - lua_newtable(L); - lua_pushstring(L, "_serializer_compact"); - lua_pushboolean(L, true); - lua_settable(L, -3); - tuple_totable_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX); - assert(tuple_totable_mt_ref != 0); - if (luaL_dostring(L, tuple_lua)) panic("Error loading Lua source %.160s...: %s", tuple_lua, lua_tostring(L, -1)); diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index 0f13b2789eaa991b9a418024e6341e4cfd607bdf..fe86828db3d6b5033f96eb12845309dcde0b015d 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -81,6 +81,30 @@ local function tuple_ipairs(tuple, pos) return it, tuple, pos end +-- a precreated metatable for totable() +local tuple_totable_mt = { + _serializer_compact = true; +} + +local function tuple_totable(tuple) + -- use a precreated iterator for tuple_next + builtin.tuple_rewind(next_it, tuple) + local ret = {} + while true do + local field = builtin.tuple_next(next_it) + if field == nil then + break + end + local val = msgpackffi.decode_unchecked(field) + table.insert(ret, val) + end + return setmetatable(ret, tuple_totable_mt) +end + +local function tuple_unpack(tuple) + return unpack(tuple_totable(tuple)) +end + -- cfuncs table is set by C part local methods = { @@ -91,8 +115,8 @@ local methods = { ["transform"] = cfuncs.transform; ["find"] = cfuncs.find; ["findall"] = cfuncs.findall; - ["unpack"] = cfuncs.unpack; - ["totable"] = cfuncs.totable; + ["unpack"] = tuple_unpack; + ["totable"] = tuple_totable; ["bsize"] = function(tuple) return tonumber(tuple._bsize) end