Allow to invoke insert/update/delete/select/replace
directly on box.space objects.
Add box.space[i]:len(), which returns the
number of tuples in the space.
Add rudimentary index object support.
Add tests.
---
core/tarantool.m | 1 +
core/tarantool_lua.m | 6 ++-
mod/box/box.lua | 27 +++++++++++++-
mod/box/box.m | 1 +
mod/box/box_lua.m | 84 +++++++++++++++++++++++++++++++++++++++---
mod/box/index.h | 18 +++++-----
mod/box/index.m | 17 ++++++++-
mod/box/memcached.m | 1 +
test/box/lua.result | Bin 8970 -> 10149 bytes
test/box/lua.test | 19 ++++++++++
test/box/reconfigure.result | 20 ++++++++++
test/box/reconfigure.test | 5 +++
test/box/tarantool_good.cfg | 2 +
13 files changed, 182 insertions(+), 19 deletions(-)
diff --git a/core/tarantool.m b/core/tarantool.m
index ae0daeb..2ec83aa 100644
--- a/core/tarantool.m
+++ b/core/tarantool.m
@@ -572,6 +572,7 @@ main(int argc, char **argv)
tarantool_L = tarantool_lua_init();
mod_init();
+ tarantool_lua_load_cfg(tarantool_L, &cfg);
admin_init();
replication_init();
diff --git a/core/tarantool_lua.m b/core/tarantool_lua.m
index b6e8b9c..d19390a 100644
--- a/core/tarantool_lua.m
+++ b/core/tarantool_lua.m
@@ -278,7 +278,6 @@ tarantool_lua_init()
luaL_register(L, "box", boxlib);
lua_pop(L, 1);
lua_register(L, "print", lbox_print);
- tarantool_lua_load_cfg(L, &cfg);
L = mod_lua_init(L);
lua_settop(L, 0); /* clear possible left-overs of init */
return L;
@@ -402,7 +401,10 @@ void tarantool_lua_load_cfg(struct lua_State *L, struct
tarantool_cfg *cfg)
"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");
+"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);
diff --git a/mod/box/box.lua b/mod/box/box.lua
index 68c1e4b..dc19c27 100644
--- a/mod/box/box.lua
+++ b/mod/box/box.lua
@@ -36,7 +36,7 @@ function box.replace(namespace, ...)
unpack(tuple))))
end
--- insert a tuple (produces an error if a tuple already exists
+-- insert a tuple (produces an error if the tuple already exists)
function box.insert(namespace, ...)
tuple = {...}
return select(2,
@@ -58,3 +58,28 @@ function box.update(namespace, key, format, ...)
#ops/2, -- op count
...)))
end
+
+function box.on_reload_configuration()
+ index_mt = {}
+ index_mt.len = function(index) return #index.idx end
+ index_mt.__newindex = function(table, index)
+ return error('Attempt to modify a read-only table') end
+ index_mt.__index = index_mt
+ space_mt = {}
+ space_mt.len = function(space) return space.index[0]:len() end
+ space_mt.__newindex = index_mt.__newindex
+ space_mt.select = function(space, ...) return box.select(space.n, ...) end
+ space_mt.insert = function(space, ...) return box.insert(space.n, ...) end
+ space_mt.update = function(space, ...) return box.update(space.n, ...) end
+ space_mt.replace = function(space, ...) return box.replace(space.n, ...)
end
+ space_mt.delete = function(space, ...) return box.delete(space.n, ...) end
+ space_mt.__index = space_mt
+ for i, space in pairs(box.space) do
+ rawset(space, 'n', i)
+ setmetatable(space, space_mt)
+ for j, index in pairs(space.index) do
+ rawset(index, 'idx', box.index.new(i, j))
+ setmetatable(index, index_mt)
+ end
+ end
+end
diff --git a/mod/box/box.m b/mod/box/box.m
index 45ea593..5f5c0c6 100644
--- a/mod/box/box.m
+++ b/mod/box/box.m
@@ -992,6 +992,7 @@ space_init(void)
index->search_pattern = palloc(eter_pool,
SIZEOF_TREE_INDEX_MEMBER(index));
index->unique = cfg_index->unique;
index->type = STR2ENUM(index_type, cfg_index->type);
+ index->n = j;
index_init(index, &space[i], cfg_space->estimated_rows);
}
diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index 8d60989..c1faca4 100644
--- a/mod/box/box_lua.m
+++ b/mod/box/box_lua.m
@@ -31,7 +31,7 @@
#include "box_lua.h"
#include "tarantool.h"
#include "box.h"
-/* use a full path to avoid clashes with system lua */
+/* use a full path to avoid clashes with system Lua */
#include "third_party/luajit/src/lua.h"
#include "third_party/luajit/src/lauxlib.h"
#include "third_party/luajit/src/lualib.h"
@@ -138,6 +138,68 @@ static const struct luaL_reg lbox_tuple_meta [] = {
/* }}} */
+/**
+ * {{{ Lua box.index library: access to spaces and indexes
+ */
+
+static const char *indexlib_name = "box.index";
+
+static struct index *
+lua_checkindex(struct lua_State *L, int i)
+{
+ struct index **index = luaL_checkudata(L, i, indexlib_name);
+ assert(index != NULL);
+ return *index;
+}
+
+static int
+lbox_index_new(struct lua_State *L)
+{
+ int n = luaL_checkint(L, 1); /* get space id */
+ int idx = luaL_checkint(L, 2); /* get index id in */
+ /* locate the appropriate index */
+ if (n >= BOX_NAMESPACE_MAX || !space[n].enabled ||
+ idx >= BOX_INDEX_MAX || space[n].index[idx].key_cardinality == 0)
+ tnt_raise(LoggedError, :ER_NO_SUCH_INDEX, idx, n);
+ /* create a userdata object */
+ void **ptr = lua_newuserdata(L, sizeof(void *));
+ *ptr = &space[n].index[idx];
+ /* set userdata object metatable to indexlib */
+ luaL_getmetatable(L, indexlib_name);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+static int
+lbox_index_tostring(struct lua_State *L)
+{
+ struct index *index = lua_checkindex(L, 1);
+ lua_pushfstring(L, "box.space[%d].index[%d]",
+ index->space->n, index->n);
+ return 1;
+}
+
+static int
+lbox_index_len(struct lua_State *L)
+{
+ struct index *index = lua_checkindex(L, 1);
+ lua_pushinteger(L, index->size(index));
+ return 1;
+}
+
+static const struct luaL_reg lbox_index_meta[] = {
+ {"__tostring", lbox_index_tostring},
+ {"__len", lbox_index_len},
+ {NULL, NULL}
+};
+
+static const struct luaL_reg indexlib [] = {
+ {"new", lbox_index_new},
+ {NULL, NULL}
+};
+
+/* }}} */
+
/** {{{ Lua I/O: facilities to intercept box output
* and push into Lua stack and the opposite: append Lua types
* to fiber IOV.
@@ -191,7 +253,6 @@ void iov_add_ret(struct lua_State *L, int index)
* and return the number of return values first, and
* then each return value as a tuple.
*/
-
void iov_add_multret(struct lua_State *L)
{
int nargs = lua_gettop(L);
@@ -364,17 +425,24 @@ void box_lua_call(struct box_txn *txn
__attribute__((unused)),
struct lua_State *
mod_lua_init(struct lua_State *L)
{
- /* box */
- luaL_register(L, "box", boxlib);
lua_atpanic(L, box_lua_panic);
- /* box.tuple */
+ /* box, box.tuple */
+ luaL_register(L, "box", boxlib);
luaL_newmetatable(L, tuplelib_name);
lua_pushstring(L, tuplelib_name);
lua_setfield(L, -2, "__metatable");
luaL_register(L, NULL, lbox_tuple_meta);
lua_pop(L, 2);
+ /* box.index */
+ luaL_newmetatable(L, indexlib_name);
+ lua_pushstring(L, indexlib_name);
+ lua_setfield(L, -2, "__metatable");
+ luaL_register(L, NULL, lbox_index_meta);
+ luaL_register(L, "box.index", indexlib);
+ lua_pop(L, 2);
/* Load box.lua */
- (void) luaL_dostring(L, &_binary_box_lua_start);
+ if (luaL_dostring(L, &_binary_box_lua_start))
+ panic("Error loading box.lua: %s", lua_tostring(L, -1));
assert(lua_gettop(L) == 0);
return L;
}
@@ -383,3 +451,7 @@ void box_lua_init()
{
root_L = tarantool_L;
}
+
+/**
+ * vim: foldmethod=marker
+ */
diff --git a/mod/box/index.h b/mod/box/index.h
index 7cb3aed..cef8588 100644
--- a/mod/box/index.h
+++ b/mod/box/index.h
@@ -76,6 +76,7 @@ struct index {
bool unique;
+ size_t (*size)(struct index *index);
struct box_tuple *(*find) (struct index * index, void *key); /* only
for unique lookups */
struct box_tuple *(*find_by_tuple) (struct index * index, struct
box_tuple * pattern);
void (*remove) (struct index * index, struct box_tuple *);
@@ -95,15 +96,14 @@ struct index {
struct space *space;
struct {
- struct {
- u32 fieldno;
- enum field_data_type type;
- } *key_field;
- u32 key_cardinality;
-
- u32 *field_cmp_order;
- u32 field_cmp_order_cnt;
- };
+ u32 fieldno;
+ enum field_data_type type;
+ } *key_field;
+ u32 *field_cmp_order;
+ u32 field_cmp_order_cnt;
+ u32 key_cardinality;
+ /* relative offset of the index in the namespace */
+ u32 n;
struct tree_index_member *search_pattern;
diff --git a/mod/box/index.m b/mod/box/index.m
index 9c9f37f..007f4ef 100644
--- a/mod/box/index.m
+++ b/mod/box/index.m
@@ -153,7 +153,11 @@ tree_index_member_compare(struct tree_index_member
*member_a, struct tree_index_
return 0;
}
-
+static size_t
+index_tree_size(struct index *index)
+{
+ return index->idx.tree->size;
+}
static struct box_tuple *
index_find_hash_by_tuple(struct index *self, struct box_tuple *tuple)
@@ -165,6 +169,13 @@ index_find_hash_by_tuple(struct index *self, struct
box_tuple *tuple)
return self->find(self, key);
}
+size_t
+index_hash_size(struct index *index)
+{
+ /* All kh_* structures have the same member layout */
+ return index->idx.hash->size;
+}
+
static struct box_tuple *
index_find_hash_num(struct index *self, void *key)
{
@@ -573,6 +584,7 @@ index_hash_num(struct index *index, struct space *space,
size_t estimated_rows)
{
index->type = HASH;
index->space = space;
+ index->size = index_hash_size;
index->find = index_find_hash_num;
index->find_by_tuple = index_find_hash_by_tuple;
index->remove = index_remove_hash_num;
@@ -593,6 +605,7 @@ index_hash_num64(struct index *index, struct space *space,
size_t estimated_rows
{
index->type = HASH;
index->space = space;
+ index->size = index_hash_size;
index->find = index_find_hash_num64;
index->find_by_tuple = index_find_hash_by_tuple;
index->remove = index_remove_hash_num64;
@@ -613,6 +626,7 @@ index_hash_str(struct index *index, struct space *space,
size_t estimated_rows)
{
index->type = HASH;
index->space = space;
+ index->size = index_hash_size;
index->find = index_find_hash_str;
index->find_by_tuple = index_find_hash_by_tuple;
index->remove = index_remove_hash_str;
@@ -634,6 +648,7 @@ index_tree(struct index *index, struct space *space,
{
index->type = TREE;
index->space = space;
+ index->size = index_tree_size;
index->find = index_find_tree;
index->find_by_tuple = index_find_tree_by_tuple;
index->remove = index_remove_tree_str;
diff --git a/mod/box/memcached.m b/mod/box/memcached.m
index 4be8722..0ac2752 100644
--- a/mod/box/memcached.m
+++ b/mod/box/memcached.m
@@ -453,6 +453,7 @@ memcached_space_init()
memc_index->unique = true;
memc_index->type = HASH;
memc_index->enabled = true;
+ memc_index->n = 0;
index_init(memc_index, memc_ns, 0);
}
diff --git a/test/box/lua.result b/test/box/lua.result
index
58c93387846484f9e6042aa9364b152ee56b7b53..389af7efd8d38919318fb6d5add7ee45cfb161f0
100644
GIT binary patch
delta 947
zcma)*u}|AT6vmYnp~`9!q@p65&_0OhCBn9nbc@ubQae<FZdE0OknMX(EzDhXK8tif
zVPNXi==N@%JFs=`QvMM3Zj9JYz(+$6o8P<l{l0hap1-~S`SJUo*YUs$uxtQ0;Pasy
z^!i1>*}lMtdvrhGtQYnZ;mMG*@%ic^#Rw&iFSqI;qc|)y2}^+oMVv+B-_~NtVifZ1
zQ|WC@U96L5sUI@WkC1kuot8Vm&i<}d7Umv4*?3fX5hY&UW^U>-JZccn4~PvUph(n@
z$Cf%RStFJl`X~U00}Lcm8~R*AEJeurO;R>o*DV{fsJ0EArr|hF*+3z<=mOc{kXu2$
z17Qpldm%%b<{+ONwC|)XWSyyB)pw(!&z23XDSSHWoUq&4bMvC~Lu;&_y@f8;w5|W^
zW<YL8hxt8}XD&}Cub!IgE6192;*dQ`LshHrSwFkazN0bny7~6mt9DeSVyP3e)_kZz
zJ5{_=FRM%2Gm87IW(IR>fNIyYHm?EQ$vQTO#8_tQ^97@b!x0w|CF<Yvl@GTvdL!A~
mZZOG!dJ+rFn?VXo_lWpk(bjObo|sFU{8SCKWUejWCAb1yEfyO9
delta 159
zcmZ4L-{m&ph)HQdN@7VWFPDOXu0m3Ng<e5XesXGYF+w0YEgiwh%qvbUDw!<7sBK)D
zSCE*TjgU%7%}GTzs2C`XY%Wmo<~Bwr8Lrg4#H5_m6e|V8$=pgho7v?!S<u8L`z!qg
E08eu-_5c6?
diff --git a/test/box/lua.test b/test/box/lua.test
index 668c216..f159150 100644
--- a/test/box/lua.test
+++ b/test/box/lua.test
@@ -110,3 +110,22 @@ exec admin "lua for k,v in pairs(box.space[0]) do if
type(v) ~= 'table' then pri
# must be read-only
exec admin "lua box.cfg.nosuchoption = 1"
exec admin "lua box.space[300] = 1"
+
+exec admin "lua box.index.new('abc', 'cde')"
+exec admin "lua box.index.new(1, 2)"
+exec admin "lua box.index.new(0, 1)"
+exec admin "lua box.index.new(0, 0)"
+exec admin "lua #box.index.new(0,0)"
+exec admin "lua #box.space[0].index[0].idx"
+exec admin "lua box.insert(0, 'test')"
+exec admin "lua box.insert(0, 'abcd')"
+exec admin "lua #box.index.new(0,0)"
+exec admin "lua #box.space[0].index[0].idx"
+exec admin "lua box.delete(0, 'test')"
+exec admin "lua #box.index.new(0,0)"
+exec admin "lua box.delete(0, 'abcd')"
+exec admin "lua #box.space[0].index[0].idx"
+exec admin "lua #box.index.new(0,0)"
+exec admin "lua box.space[0]:insert('test', 'hello world')"
+exec admin "lua box.space[0]:update('test', '=p', 1, 'bye, world')"
+exec admin "lua box.space[0]:delete('test')"
diff --git a/test/box/reconfigure.result b/test/box/reconfigure.result
index 8c11829..71a03e4 100644
--- a/test/box/reconfigure.result
+++ b/test/box/reconfigure.result
@@ -1,3 +1,7 @@
+lua box.cfg.too_long_threshold
+---
+ - 0.5
+...
reload configuration
---
fail:
@@ -14,6 +18,10 @@ fail:
- Could not accept read only 'space[0].index[0].key_field[0].fieldno' option
- Could not accept read only 'space[0].index[0].key_field[0].type' option
...
+lua box.cfg.too_long_threshold
+---
+ - 0.5
+...
reload configuration
---
fail:
@@ -41,11 +49,19 @@ reload configuration
---
ok
...
+lua box.cfg.too_long_threshold
+---
+ - 2
+...
reload configuration
---
fail:
- gram_yyerror: syntax error, unexpected $end, expecting KEY_P or NULL_P or
'[' at line 1
...
+lua box.cfg.too_long_threshold
+---
+ - 2
+...
reload configuration
---
fail:
@@ -55,6 +71,10 @@ reload configuration
---
ok
...
+lua box.cfg.too_long_threshold
+---
+ - 0.5
+...
#
# A test case for http://bugs.launchpad.net/bugs/712447:
# Valgrind reports use of not initialized memory after 'reload
diff --git a/test/box/reconfigure.test b/test/box/reconfigure.test
index f21546d..4ca5874 100644
--- a/test/box/reconfigure.test
+++ b/test/box/reconfigure.test
@@ -1,7 +1,9 @@
# encoding: tarantool
#
+exec admin "lua box.cfg.too_long_threshold"
# bad1
server.reconfigure("box/tarantool_bad1.cfg")
+exec admin "lua box.cfg.too_long_threshold"
# bad2
server.reconfigure("box/tarantool_bad2.cfg")
# bad3
@@ -12,8 +14,10 @@ server.reconfigure("box/tarantool_bad4.cfg")
server.reconfigure("box/tarantool_bad5.cfg")
# good
server.reconfigure("box/tarantool_good.cfg")
+exec admin "lua box.cfg.too_long_threshold"
# empty
server.reconfigure("box/tarantool_empty.cfg")
+exec admin "lua box.cfg.too_long_threshold"
# no config
server.reconfigure(None)
@@ -21,6 +25,7 @@ server.reconfigure(None)
# cleanup
# restore default
server.reconfigure(self.suite_ini["config"])
+exec admin "lua box.cfg.too_long_threshold"
print """#
# A test case for http://bugs.launchpad.net/bugs/712447:
diff --git a/test/box/tarantool_good.cfg b/test/box/tarantool_good.cfg
index 0ec29f2..9826f7c 100644
--- a/test/box/tarantool_good.cfg
+++ b/test/box/tarantool_good.cfg
@@ -9,6 +9,8 @@ secondary_port = 33014
admin_port = 33015
rows_per_wal = 50
+# This is one of the few modifiable settings, change it
+too_long_threshold=2
space[0].enabled = 1
space[0].index[0].type = "HASH"
--
1.7.0.4
_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help : https://help.launchpad.net/ListHelp