diff --git a/src/box/lua/tuple.cc b/src/box/lua/tuple.cc index f67e23d59bd07a46765754080c453d41a21ad703..00d8856bc993d7c45ae83ed7cfdf07220e984240 100644 --- a/src/box/lua/tuple.cc +++ b/src/box/lua/tuple.cc @@ -90,6 +90,39 @@ lua_istuple(struct lua_State *L, int narg) return t; } +static int +lbox_tuple_new(lua_State *L) +{ + int argc = lua_gettop(L); + if (unlikely(argc < 1)) { + lua_newtable(L); /* create an empty tuple */ + ++argc; + } + + struct region *gc = &fiber()->gc; + RegionGuard guard(gc); + struct mpstream stream; + mpstream_init(&stream, gc, region_reserve_cb, region_alloc_cb); + + if (argc == 1 && (lua_istable(L, 1) || lua_istuple(L, 1))) { + /* New format: box.tuple.new({1, 2, 3}) */ + luamp_encode_tuple(L, luaL_msgpack_default, &stream, 1); + } else { + /* Backward-compatible format: box.tuple.new(1, 2, 3). */ + luamp_encode_array(luaL_msgpack_default, &stream, argc); + for (int k = 1; k <= argc; ++k) { + luamp_encode(L, luaL_msgpack_default, &stream, k); + } + } + mpstream_flush(&stream); + + size_t tuple_len = region_used(gc) - guard.used; + const char *data = (char *) region_join(gc, tuple_len); + struct tuple *tuple = tuple_new(tuple_format_ber, data, data + tuple_len); + lbox_pushtuple(L, tuple); + return 1; +} + static int lbox_tuple_gc(struct lua_State *L) { @@ -326,6 +359,11 @@ static const struct luaL_reg lbox_tuple_meta[] = { {NULL, NULL} }; +static const struct luaL_reg lbox_tuplelib[] = { + {"new", lbox_tuple_new}, + {NULL, NULL} +}; + static const struct luaL_reg lbox_tuple_iterator_meta[] = { {NULL, NULL} }; @@ -342,6 +380,8 @@ box_lua_tuple_init(struct lua_State *L) lua_setglobal(L, "cfuncs"); luaL_register_type(L, tuple_iteratorlib_name, lbox_tuple_iterator_meta); + luaL_register_module(L, tuplelib_name, lbox_tuplelib); + lua_pop(L, 1); luamp_set_encode_extension(luamp_encode_extension_box); diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index a394abad97cd1b4189f500bfbb258a457dc6b8d5..f7dba0df8766797226159b222482c34b014a9e1a 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -85,32 +85,6 @@ local tuple_bless = function(tuple) return ffi.gc(ffi.cast(const_tuple_ref_t, tuple), tuple_gc) end -local format_lua = nil -- cached box_tuple_format -local function tuple_new(...) - if format_lua == nil then - format_lua = builtin.box_tuple_format_default() - end - - local obj = ... - if select('#', ...) > 1 or type(obj) ~= 'table' then - -- Backward-compatible format: box.tuple.new(1, 2, 3). - obj = {} - for i=1,select('#', ...) do - local val = select(i, ...) - if val == nil then - val = msgpackffi.NULL - end - obj[i] = val - end - end - local data, data_end = msgpackffi.encode_tuple(obj) - local tuple = builtin.box_tuple_new(format_lua, data, data_end) - if tuple == nil then - return box.error() - end - return tuple_bless(tuple) -end - local tuple_iterator_t = ffi.typeof('box_tuple_iterator_t') local tuple_iterator_ref_t = ffi.typeof('box_tuple_iterator_t &') @@ -322,8 +296,5 @@ ffi.metatype(tuple_iterator_t, { -- Remove the global variable cfuncs = nil -box.tuple = { - new = tuple_new; - -- internal api for box.select and iterators - bless = tuple_bless; -} +-- internal api for box.select and iterators +box.tuple.bless = tuple_bless diff --git a/src/sio.cc b/src/sio.cc index 9f79f972956133d6f01c6ada0a040ee9db93e898..f76c53b08fb5b6e29c280030ef4442b688c03be6 100644 --- a/src/sio.cc +++ b/src/sio.cc @@ -214,7 +214,7 @@ sio_connect(int fd, struct sockaddr *addr, socklen_t addrlen) /* Establish the connection. */ int rc = connect(fd, (struct sockaddr *) addr, addrlen); if (rc < 0 && errno != EINPROGRESS) { - tnt_raise(SocketError, fd, "connect"); + tnt_raise(SocketError, fd, "connect to %s", sio_strfaddr((struct sockaddr *)addr, addrlen)); } return rc; } diff --git a/test/big/lua.result b/test/big/lua.result index 4274109f5f0a03b99d32d98800b86e398d8f15fd..bc373b70c24b33ec882dd669dd435e2dba3ec5a7 100644 --- a/test/big/lua.result +++ b/test/big/lua.result @@ -734,7 +734,7 @@ t:find(2, '2') ... t:find(89, '2') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(4, '3') --- diff --git a/test/box/tuple.result b/test/box/tuple.result index b7eb8ad455172a142c1962a0617ea50b6f6c498e..15975979bd1125c2e53cb3ec986fd32c725cb5c9 100644 --- a/test/box/tuple.result +++ b/test/box/tuple.result @@ -305,12 +305,12 @@ t:unpack(2, 1) ... t:totable(0) --- -- error: '[string "-- tuple.lua (internal file)..."]:182: tuple.totable: invalid second +- error: '[string "-- tuple.lua (internal file)..."]:156: tuple.totable: invalid second argument' ... t:totable(1, 0) --- -- error: '[string "-- tuple.lua (internal file)..."]:191: tuple.totable: invalid third +- error: '[string "-- tuple.lua (internal file)..."]:165: tuple.totable: invalid third argument' ... -- @@ -443,7 +443,7 @@ t:next(-1) ... t:next("fdsaf") --- -- error: '[string "-- tuple.lua (internal file)..."]:163: bad argument #2 to ''box_tuple_field'' +- error: '[string "-- tuple.lua (internal file)..."]:137: bad argument #2 to ''box_tuple_field'' (cannot convert ''string'' to ''unsigned int'')' ... box.tuple.new({'x', 'y', 'z'}):next() @@ -612,7 +612,7 @@ r = {} ... for _state, val in t:pairs(10) do table.insert(r, val) end --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... r --- @@ -698,19 +698,19 @@ t:findall(1, 'xxxxx') ... t:find(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(100, 'a') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:find(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... t:findall(100, 'xxxxx') --- -- error: '[string "-- tuple.lua (internal file)..."]:151: error: invalid key to ''next''' +- error: '[string "-- tuple.lua (internal file)..."]:125: error: invalid key to ''next''' ... --- -- Lua type coercion @@ -804,12 +804,12 @@ t = box.tuple.new({'a', 'b', 'c', 'd', 'e'}) ... t:update() --- -- error: '[string "-- tuple.lua (internal file)..."]:231: Usage: tuple:update({ { +- error: '[string "-- tuple.lua (internal file)..."]:205: Usage: tuple:update({ { op, field, arg}+ })' ... t:update(10) --- -- error: '[string "-- tuple.lua (internal file)..."]:231: Usage: tuple:update({ { +- error: '[string "-- tuple.lua (internal file)..."]:205: Usage: tuple:update({ { op, field, arg}+ })' ... t:update({}) diff --git a/test/wal_off/oom.result b/test/wal_off/oom.result index c629d4662349dc51444cbac6de7bf947fcb6f021..fa357432069c848967894e6ab0bef8d39c5986a9 100644 --- a/test/wal_off/oom.result +++ b/test/wal_off/oom.result @@ -218,6 +218,10 @@ space = box.schema.space.create('tweedledum') index = space:create_index('primary', { type = 'hash' }) --- ... +collectgarbage('collect') +--- +- 0 +... for i=1,10000 do space:insert{i, str} end --- - error: Failed to allocate 15019 bytes in slab allocator for tuple @@ -239,6 +243,10 @@ index:count() --- - 0 ... +collectgarbage('collect') +--- +- 0 +... for i=1,10000 do space:insert{i, str} end --- - error: Failed to allocate 15019 bytes in slab allocator for tuple diff --git a/test/wal_off/oom.test.lua b/test/wal_off/oom.test.lua index 2ebdf96f816cec4bb81136a522dbeaad4901ee6e..88a1f0fb4e32622ca5c9323ce89c44877df06488 100644 --- a/test/wal_off/oom.test.lua +++ b/test/wal_off/oom.test.lua @@ -85,6 +85,7 @@ str = string.rep('a', 15000) -- about size of index memory block space = box.schema.space.create('tweedledum') index = space:create_index('primary', { type = 'hash' }) +collectgarbage('collect') for i=1,10000 do space:insert{i, str} end definatelly_used = index:count() * 16 * 1024 2 * definatelly_used > arena_bytes -- at least half memory used @@ -92,6 +93,7 @@ to_del = index:count() for i=1,to_del do space:delete{i} end index:count() +collectgarbage('collect') for i=1,10000 do space:insert{i, str} end definatelly_used = index:count() * 16 * 1024 2 * definatelly_used > arena_bytes -- at least half memory used