From 02a12f75039f27f086a828c28f12cca54c3e0639 Mon Sep 17 00:00:00 2001 From: "Dmitry E. Oboukhov" <unera@debian.org> Date: Wed, 28 Nov 2012 18:02:03 +0400 Subject: [PATCH] spaces represent in lua by lbox_pushspace() --- src/CMakeLists.txt | 1 + src/box/box.lua | 20 ++--- src/box/index.h | 1 + src/box/space.m | 6 ++ src/lua/init.m | 45 +++++------- src/lua/space.h | 40 ++++++++++ src/lua/space.m | 166 ++++++++++++++++++++++++++++++++++++++++++ src/memcached.m | 1 + src/tarantool.m | 2 +- test/box/admin.test | 1 + test/box/lua.result | 15 ++-- test/box/space.result | 17 +++++ test/box/space.test | 5 ++ test/run | 14 +++- test/tarantool | 1 - 15 files changed, 287 insertions(+), 48 deletions(-) create mode 100644 src/lua/space.h create mode 100644 src/lua/space.m create mode 100644 test/box/space.result create mode 100644 test/box/space.test mode change 120000 => 100755 test/run delete mode 120000 test/tarantool diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc8a9e86c8..f4b27c6cd6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,7 @@ set (common_sources lua/slab.m lua/uuid.m lua/lua_ipc.m + lua/space.m ) if (ENABLE_TRACE) diff --git a/src/box/box.lua b/src/box/box.lua index 2f68c47aa8..238aee1925 100644 --- a/src/box/box.lua +++ b/src/box/box.lua @@ -173,7 +173,7 @@ function box.counter.dec(space, ...) end end -function box.on_reload_configuration() +function box.bless_space(space) local index_mt = {} -- __len and __index index_mt.len = function(index) return #index.idx end @@ -254,18 +254,20 @@ function box.on_reload_configuration() end space_mt.pairs = function(space) return space.index[0]:pairs() end space_mt.__index = space_mt - for i, space in pairs(box.space) do - rawset(space, 'n', i) - setmetatable(space, space_mt) - if type(space.index) == 'table' and space.enabled then - for j, index in pairs(space.index) do - rawset(index, 'idx', box.index.new(i, j)) - setmetatable(index, index_mt) - end + + setmetatable(space, space_mt) + if type(space.index) == 'table' and space.enabled then + for j, index in pairs(space.index) do + rawset(index, 'idx', box.index.new(space.n, j)) + setmetatable(index, index_mt) end end end +-- User can redefine the hook +function box.on_reload_configuration() +end + require("bit") -- vim: set et ts=4 sts diff --git a/src/box/index.h b/src/box/index.h index f77bb465dd..fae5231dc7 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -77,6 +77,7 @@ struct key_def { */ int max_fieldno; bool is_unique; + enum index_type type; }; /** Descriptor of index features. */ diff --git a/src/box/space.m b/src/box/space.m index 5a08e1b2e9..5903926f2c 100644 --- a/src/box/space.m +++ b/src/box/space.m @@ -216,6 +216,12 @@ key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) { def->max_fieldno = 0; def->part_count = 0; + if (strcmp(cfg_index->type, "HASH") == 0) + def->type = HASH; + else if (strcmp(cfg_index->type, "TREE") == 0) + def->type = TREE; + else + panic("Wrong index type: %s", cfg_index->type); /* Calculate key part count and maximal field number. */ for (int k = 0; cfg_index->key_field[k] != NULL; ++k) { diff --git a/src/lua/init.m b/src/lua/init.m index 527c67ce98..e1b7beae3e 100644 --- a/src/lua/init.m +++ b/src/lua/init.m @@ -48,6 +48,7 @@ #include "lua/slab.h" #include "lua/stat.h" #include "lua/uuid.h" +#include "space.h" #include TARANTOOL_CONFIG @@ -1374,14 +1375,13 @@ tarantool_lua_load_cfg(struct lua_State *L, struct tarantool_cfg *cfg) luaL_addstring(&b, "box.cfg = {}\n" "setmetatable(box.cfg, {})\n" - "box.space = {}\n" - "setmetatable(box.space, getmetatable(box.cfg))\n" - "getmetatable(box.space).__index = " + "getmetatable(box.cfg).__index = " "function(table, index)\n" " table[index] = {}\n" " setmetatable(table[index], getmetatable(table))\n" " return rawget(table, index)\n" - "end\n"); + "end\n" + ); while ((key = tarantool_cfg_iterator_next(i, cfg, &value)) != NULL) { if (value == NULL) continue; @@ -1390,44 +1390,33 @@ tarantool_lua_load_cfg(struct lua_State *L, struct tarantool_cfg *cfg) lua_pushfstring(L, "box.cfg.%s = %s%s%s\n", key, quote, value, quote); luaL_addvalue(&b); - } else if (strncmp(key, "space", strlen("space")) == 0) { - lua_pushfstring(L, "box.%s = %s%s%s\n", - key, quote, value, quote); - luaL_addvalue(&b); } free(value); } - if (cfg->memcached_port) { - lua_pushfstring(L, - "box.space[%d].enabled = true\n" - "box.space[%d].cardinality = 4\n" - "box.space[%d].estimated_rows = 0\n" - "box.space[%d].index[0].unique = true\n" - "box.space[%d].index[0].type = 'HASH'\n" - "box.space[%d].index[0].key_field[0].field_no = 0\n" - "box.space[%d].index[0].key_field[0].field_type = 'STRING'\n", - cfg->memcached_space, cfg->memcached_space, - cfg->memcached_space, cfg->memcached_space, - cfg->memcached_space, cfg->memcached_space, - cfg->memcached_space); - luaL_addvalue(&b); - } + luaL_addstring(&b, "getmetatable(box.cfg).__newindex = " "function(table, index)\n" " error('Attempt to modify a read-only table')\n" "end\n" "getmetatable(box.cfg).__index = nil\n" - "if type(box.on_reload_configuration) == 'function' " - "then\n" - " box.on_reload_configuration()\n" - "end\n"); + ); luaL_pushresult(&b); if (luaL_loadstring(L, lua_tostring(L, -1)) != 0 || lua_pcall(L, 0, 0, 0) != 0) { panic("%s", lua_tostring(L, -1)); } - lua_pop(L, 1); + lua_pop(L, 1); /* cleanup stack */ + + lbox_space_init(L); + + /* on_reload_configuration hook */ + lua_getfield(L, LUA_GLOBALSINDEX, "box"); + lua_pushstring(L, "on_reload_configuration"); + lua_gettable(L, -2); + if (lua_isfunction(L, -1)) + lua_call(L, 0, 0); + lua_pop(L, 1); /* cleanup stack */ } /** diff --git a/src/lua/space.h b/src/lua/space.h new file mode 100644 index 0000000000..a6ee38d2a4 --- /dev/null +++ b/src/lua/space.h @@ -0,0 +1,40 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef INCLUDES_TARANTOOL_LUA_SPACE_H +#define INCLUDES_TARANTOOL_LUA_SPACE_H + + +struct lua_State; +struct space; + +int lbox_pushspace(struct lua_State *L, struct space *space); +void lbox_space_init(struct lua_State *L); + +#endif /* INCLUDES_TARANTOOL_LUA_SPACE_H */ diff --git a/src/lua/space.m b/src/lua/space.m new file mode 100644 index 0000000000..c3526535c7 --- /dev/null +++ b/src/lua/space.m @@ -0,0 +1,166 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "space.h" +#include "../box/space.h" +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include <say.h> + + +int +lbox_pushspace(struct lua_State *L, struct space *space) +{ + lua_newtable(L); + + /* space.cardinality */ + lua_pushstring(L, "cardinality"); + lua_pushnumber(L, space->arity); + lua_settable(L, -3); + + /* space.n */ + lua_pushstring(L, "n"); + lua_pushnumber(L, space->no); + lua_settable(L, -3); + + /* all exists spaces are enabled */ + lua_pushstring(L, "enabled"); + lua_pushboolean(L, 1); + lua_settable(L, -3); + + /* legacy field */ + lua_pushstring(L, "estimated_rows"); + lua_pushnumber(L, 0); + lua_settable(L, -3); + + /* space.index */ + lua_pushstring(L, "index"); + lua_newtable(L); + + + for(int i = 0; i < space->key_count; i++) { + lua_pushnumber(L, i); + lua_newtable(L); /* space.index[i] */ + + lua_pushstring(L, "idx"); + lua_pushfstring(L, "index %d in space %d", i, space->no); + lua_settable(L, -3); + + lua_pushstring(L, "unique"); + lua_pushboolean(L, space->key_defs[i].is_unique); + lua_settable(L, -3); + + lua_pushstring(L, "type"); + switch(space->key_defs[i].type) { + case HASH: + lua_pushstring(L, "HASH"); + break; + case TREE: + lua_pushstring(L, "TREE"); + break; + default: + panic("unknown index type %d", + space->key_defs[i].parts[0].type); + } + lua_settable(L, -3); + + lua_pushstring(L, "key_field"); + lua_newtable(L); + + for (int j = 0; j < space->key_defs[i].part_count; j++) { + lua_pushnumber(L, j); + lua_newtable(L); + + lua_pushstring(L, "type"); + switch(space->key_defs[i].parts[j].type) { + case NUM: + lua_pushstring(L, "NUM"); + break; + case NUM64: + lua_pushstring(L, "NUM64"); + break; + case STRING: + lua_pushstring(L, "STR"); + break; + default: + lua_pushstring(L, "UNKNOWN"); + break; + } + lua_settable(L, -3); + + lua_pushstring(L, "fieldno"); + lua_pushnumber(L, space->key_defs[i].parts[j].fieldno); + lua_settable(L, -3); + + lua_settable(L, -3); + } + + lua_settable(L, -3); /* space[i].key_field */ + + lua_settable(L, -3); /* space[i] */ + } + + lua_settable(L, -3); /* push space.index */ + + + /* on_reload_configuration hook */ + lua_getfield(L, LUA_GLOBALSINDEX, "box"); + lua_pushstring(L, "bless_space"); + lua_gettable(L, -2); + + if (!lua_isfunction(L, -1)) + panic("box.bless_space isn't a function"); + + lua_pushvalue(L, -3); /* box, bless, space */ + lua_call(L, 1, 0); + lua_pop(L, 1); /* cleanup stack */ + + return 1; +} + +static void +lbox_add_space(struct space *space, struct lua_State *L) +{ + lua_pushnumber(L, space->no); + lbox_pushspace(L, space); + lua_settable(L, -3); +} + +void +lbox_space_init(struct lua_State *L) +{ + lua_getfield(L, LUA_GLOBALSINDEX, "box"); + lua_pushstring(L, "space"); + lua_newtable(L); + space_foreach((void *)lbox_add_space, L); /* fill box.space */ + lua_settable(L, -3); + lua_pop(L, 1); + assert(lua_gettop(L) == 0); +} diff --git a/src/memcached.m b/src/memcached.m index 166148745d..0c77fdecef 100644 --- a/src/memcached.m +++ b/src/memcached.m @@ -469,6 +469,7 @@ memcached_space_init() struct key_def *key_def = malloc(sizeof(struct key_def)); key_def->part_count = 1; key_def->is_unique = true; + key_def->type = HASH; key_def->parts = malloc(sizeof(struct key_part)); key_def->cmp_order = malloc(sizeof(u32)); diff --git a/src/tarantool.m b/src/tarantool.m index e04d82251f..c0ee8387cc 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -860,8 +860,8 @@ main(int argc, char **argv) @try { tarantool_L = tarantool_lua_init(); mod_init(); - tarantool_lua_load_cfg(tarantool_L, &cfg); memcached_init(cfg.bind_ipaddr, cfg.memcached_port); + tarantool_lua_load_cfg(tarantool_L, &cfg); /* * init iproto before admin and after memcached: * recovery is finished on bind to the primary port, diff --git a/test/box/admin.test b/test/box/admin.test index b1877799ff..eb9f210869 100644 --- a/test/box/admin.test +++ b/test/box/admin.test @@ -25,4 +25,5 @@ exec admin "show fiber" exec admin "show slab" exec admin "show palloc" sys.stdout.clear_all_filters() + # vim: syntax=python diff --git a/test/box/lua.result b/test/box/lua.result index e57c46d84d..4e07b73339 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -20,9 +20,10 @@ lua for n in pairs(box) do print(' - box.', n) end - box.replace - box.space - box.cfg + - box.on_reload_configuration - box.select_range - box.insert - - box.on_reload_configuration + - box.bless_space - box.counter - box.info - box.auto_increment @@ -401,8 +402,8 @@ lua for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then print(' - ', k, --- - cardinality: -1 - estimated_rows: 0 - - enabled: true - n: 0 + - enabled: true ... reload configuration --- @@ -449,16 +450,15 @@ lua for k,v in pairs(box.space[0]) do if type(v) ~= 'table' then print(' - ', k, --- - cardinality: -1 - estimated_rows: 0 - - enabled: true - n: 0 + - enabled: true ... lua box.cfg.nosuchoption = 1 --- -error: '[string "box.cfg = {}..."]:52: Attempt to modify a read-only table' +error: '[string "box.cfg = {}..."]:43: Attempt to modify a read-only table' ... lua box.space[300] = 1 --- -error: '[string "box.cfg = {}..."]:52: Attempt to modify a read-only table' ... lua box.index.new('abc', 'cde') --- @@ -699,12 +699,11 @@ lua box.fiber.resume(f, 'hello', 'world') ... lua box.fiber.resume(f, 'wide') --- - - world - - wide +error: 'fiber.resume(): the fiber is dead' ... lua box.fiber.resume(f) --- - - true +error: 'fiber.resume(): the fiber is dead' ... lua function y() print('started') box.fiber.detach() while true do box.replace(0, 'test', os.time()) box.fiber.sleep(0.001) end end --- diff --git a/test/box/space.result b/test/box/space.result new file mode 100644 index 0000000000..4d48f37e12 --- /dev/null +++ b/test/box/space.result @@ -0,0 +1,17 @@ +lua type(box) +--- + - table +... +lua type(box.space) +--- + - table +... +lua box.cfg.memcached_space +--- + - 23 +... +lua for i, v in pairs(box.space[0].index[0].key_field[0]) do print(i, ': ', v) end +--- +type: NUM +fieldno: 0 +... diff --git a/test/box/space.test b/test/box/space.test new file mode 100644 index 0000000000..a421d26852 --- /dev/null +++ b/test/box/space.test @@ -0,0 +1,5 @@ +# encoding: tarantool +exec admin "lua type(box)" +exec admin "lua type(box.space)" +exec admin "lua box.cfg.memcached_space" +exec admin "lua for i, v in pairs(box.space[0].index[0].key_field[0]) do print(i, ': ', v) end" diff --git a/test/run b/test/run deleted file mode 120000 index 68f68dd767..0000000000 --- a/test/run +++ /dev/null @@ -1 +0,0 @@ -./run.sh \ No newline at end of file diff --git a/test/run b/test/run new file mode 100755 index 0000000000..351474a9b4 --- /dev/null +++ b/test/run @@ -0,0 +1,13 @@ +#!/bin/sh + +/usr/bin/env python <<__EOB__ +import sys +if sys.hexversion < 0x02060000 or sys.hexversion >= 0x03000000: + sys.stderr.write("ERROR: test harness must use python >= 2.6 but not 3.x\n") + sys.exit(1) +else: + sys.exit(0) +__EOB__ + +[ $? -eq 0 ] && ./test-run.py $* + diff --git a/test/tarantool b/test/tarantool deleted file mode 120000 index eb4a53a749..0000000000 --- a/test/tarantool +++ /dev/null @@ -1 +0,0 @@ -../client/tarantool/tarantool \ No newline at end of file -- GitLab