From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com, Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Subject: [PATCH v2 2/3] schema: inherit vinyl/memtx_index_mt from base index mt
Date: Tue, 3 Apr 2018 19:50:46 +0300 [thread overview]
Message-ID: <d7fda3e42181f04fcbfa6e37a17f8b036dc4945e.1522774214.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1522774214.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1522774214.git.v.shpilevoy@tarantool.org>
Now space.bless() in Lua serves to choose a correct index
metatable that depends on a space engine. Vinyl index methods
must not use FFI since yield breaks it. Lets do not choose
correct methods one by one in space.bless, create them only
once on start, and then just do copy of needed table.
---
src/box/lua/schema.lua | 109 ++++++++++++++++++++++++++++++-------------------
1 file changed, 66 insertions(+), 43 deletions(-)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 8b6f69ad8..4b5eeeda9 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1074,9 +1074,32 @@ end
internal.check_iterator_type = check_iterator_type -- export for net.box
-local index_mt = {}
+local function forbid_new_index(t, k, v)
+ return error('Attempt to modify a read-only table')
+end
+
+local base_index_mt = {}
+base_index_mt.__index = base_index_mt
+--
+-- Inherit engine specific index metatables from a base one.
+--
+local vinyl_index_mt = {}
+vinyl_index_mt.__index = vinyl_index_mt
+local memtx_index_mt = {}
+memtx_index_mt.__index = memtx_index_mt
+--
+-- When a new method is added below to base index mt, the same
+-- method is added both to vinyl and memtx index mt.
+--
+setmetatable(base_index_mt, {
+ __newindex = function(t, k, v)
+ vinyl_index_mt[k] = v
+ memtx_index_mt[k] = v
+ rawset(t, k, v)
+ end
+})
-- __len and __index
-index_mt.len = function(index)
+base_index_mt.len = function(index)
check_index_arg(index, 'len')
local ret = builtin.box_index_len(index.space_id, index.id)
if ret == -1 then
@@ -1085,7 +1108,7 @@ index_mt.len = function(index)
return tonumber(ret)
end
-- index.bsize
-index_mt.bsize = function(index)
+base_index_mt.bsize = function(index)
check_index_arg(index, 'bsize')
local ret = builtin.box_index_bsize(index.space_id, index.id)
if ret == -1 then
@@ -1093,13 +1116,11 @@ index_mt.bsize = function(index)
end
return tonumber(ret)
end
-index_mt.__len = index_mt.len -- Lua 5.2 compatibility
-index_mt.__newindex = function(table, index)
- return error('Attempt to modify a read-only table')
-end
-index_mt.__index = index_mt
+-- Lua 5.2 compatibility
+base_index_mt.__len = base_index_mt.len
+base_index_mt.__newindex = forbid_new_index
-- min and max
-index_mt.min_ffi = function(index, key)
+base_index_mt.min_ffi = function(index, key)
check_index_arg(index, 'min')
local pkey, pkey_end = tuple_encode(key)
if builtin.box_index_min(index.space_id, index.id,
@@ -1111,12 +1132,12 @@ index_mt.min_ffi = function(index, key)
return
end
end
-index_mt.min_luac = function(index, key)
+base_index_mt.min_luac = function(index, key)
check_index_arg(index, 'min')
key = keify(key)
return internal.min(index.space_id, index.id, key);
end
-index_mt.max_ffi = function(index, key)
+base_index_mt.max_ffi = function(index, key)
check_index_arg(index, 'max')
local pkey, pkey_end = tuple_encode(key)
if builtin.box_index_max(index.space_id, index.id,
@@ -1128,12 +1149,12 @@ index_mt.max_ffi = function(index, key)
return
end
end
-index_mt.max_luac = function(index, key)
+base_index_mt.max_luac = function(index, key)
check_index_arg(index, 'max')
key = keify(key)
return internal.max(index.space_id, index.id, key);
end
-index_mt.random_ffi = function(index, rnd)
+base_index_mt.random_ffi = function(index, rnd)
check_index_arg(index, 'random')
rnd = rnd or math.random()
if builtin.box_index_random(index.space_id, index.id, rnd,
@@ -1145,13 +1166,13 @@ index_mt.random_ffi = function(index, rnd)
return
end
end
-index_mt.random_luac = function(index, rnd)
+base_index_mt.random_luac = function(index, rnd)
check_index_arg(index, 'random')
rnd = rnd or math.random()
return internal.random(index.space_id, index.id, rnd);
end
-- iteration
-index_mt.pairs_ffi = function(index, key, opts)
+base_index_mt.pairs_ffi = function(index, key, opts)
check_index_arg(index, 'pairs')
local pkey, pkey_end = tuple_encode(key)
local itype = check_iterator_type(opts, pkey + 1 >= pkey_end);
@@ -1166,7 +1187,7 @@ index_mt.pairs_ffi = function(index, key, opts)
return fun.wrap(iterator_gen, keybuf,
ffi.gc(cdata, builtin.box_iterator_free))
end
-index_mt.pairs_luac = function(index, key, opts)
+base_index_mt.pairs_luac = function(index, key, opts)
check_index_arg(index, 'pairs')
key = keify(key)
local itype = check_iterator_type(opts, #key == 0);
@@ -1178,7 +1199,7 @@ index_mt.pairs_luac = function(index, key, opts)
end
-- index subtree size
-index_mt.count_ffi = function(index, key, opts)
+base_index_mt.count_ffi = function(index, key, opts)
check_index_arg(index, 'count')
local pkey, pkey_end = tuple_encode(key)
local itype = check_iterator_type(opts, pkey + 1 >= pkey_end);
@@ -1189,14 +1210,14 @@ index_mt.count_ffi = function(index, key, opts)
end
return tonumber(count)
end
-index_mt.count_luac = function(index, key, opts)
+base_index_mt.count_luac = function(index, key, opts)
check_index_arg(index, 'count')
key = keify(key)
local itype = check_iterator_type(opts, #key == 0);
return internal.count(index.space_id, index.id, itype, key);
end
-index_mt.get_ffi = function(index, key)
+base_index_mt.get_ffi = function(index, key)
check_index_arg(index, 'get')
local key, key_end = tuple_encode(key)
if builtin.box_index_get(index.space_id, index.id,
@@ -1208,7 +1229,7 @@ index_mt.get_ffi = function(index, key)
return
end
end
-index_mt.get_luac = function(index, key)
+base_index_mt.get_luac = function(index, key)
check_index_arg(index, 'get')
key = keify(key)
return internal.get(index.space_id, index.id, key)
@@ -1229,7 +1250,7 @@ local function check_select_opts(opts, key_is_nil)
return iterator, offset, limit
end
-index_mt.select_ffi = function(index, key, opts)
+base_index_mt.select_ffi = function(index, key, opts)
check_index_arg(index, 'select')
local key, key_end = tuple_encode(key)
local iterator, offset, limit = check_select_opts(opts, key + 1 >= key_end)
@@ -1251,7 +1272,7 @@ index_mt.select_ffi = function(index, key, opts)
return ret
end
-index_mt.select_luac = function(index, key, opts)
+base_index_mt.select_luac = function(index, key, opts)
check_index_arg(index, 'select')
local key = keify(key)
local iterator, offset, limit = check_select_opts(opts, #key == 0)
@@ -1259,28 +1280,28 @@ index_mt.select_luac = function(index, key, opts)
offset, limit, key)
end
-index_mt.update = function(index, key, ops)
+base_index_mt.update = function(index, key, ops)
check_index_arg(index, 'update')
return internal.update(index.space_id, index.id, keify(key), ops);
end
-index_mt.delete = function(index, key)
+base_index_mt.delete = function(index, key)
check_index_arg(index, 'delete')
return internal.delete(index.space_id, index.id, keify(key));
end
-index_mt.info = function(index)
+base_index_mt.info = function(index)
return internal.info(index.space_id, index.id);
end
-index_mt.drop = function(index)
+base_index_mt.drop = function(index)
check_index_arg(index, 'drop')
return box.schema.index.drop(index.space_id, index.id)
end
-index_mt.rename = function(index, name)
+base_index_mt.rename = function(index, name)
check_index_arg(index, 'rename')
return box.schema.index.rename(index.space_id, index.id, name)
end
-index_mt.alter = function(index, options)
+base_index_mt.alter = function(index, options)
check_index_arg(index, 'alter')
if index.id == nil or index.space_id == nil then
box.error(box.error.PROC_LUA, "Usage: index:alter{opts}")
@@ -1288,6 +1309,17 @@ index_mt.alter = function(index, options)
return box.schema.index.alter(index.space_id, index.id, options)
end
+local read_ops = {'select', 'get', 'min', 'max', 'count', 'random', 'pairs'}
+for _, op in ipairs(read_ops) do
+ vinyl_index_mt[op] = base_index_mt[op..'_luac']
+ memtx_index_mt[op] = base_index_mt[op..'_ffi']
+end
+-- Lua 5.2 compatibility
+vinyl_index_mt.__pairs = vinyl_index_mt.pairs
+vinyl_index_mt.__ipairs = vinyl_index_mt.pairs
+memtx_index_mt.__pairs = memtx_index_mt.pairs
+memtx_index_mt.__ipairs = memtx_index_mt.pairs
+
local space_mt = {}
space_mt.len = function(space)
check_space_arg(space, 'len')
@@ -1313,7 +1345,7 @@ space_mt.bsize = function(space)
end
return builtin.space_bsize(s)
end
-space_mt.__newindex = index_mt.__newindex
+space_mt.__newindex = forbid_new_index
space_mt.get = function(space, key)
check_space_arg(space, 'get')
@@ -1409,22 +1441,13 @@ end
space_mt.__index = space_mt
function box.schema.space.bless(space)
- local index_mt = table.deepcopy(index_mt)
local space_mt = table.deepcopy(space_mt)
- -- true if reading operations may yield
- local read_yields = space.engine == 'vinyl'
- local read_ops = {'select', 'get', 'min', 'max', 'count', 'random', 'pairs'}
- for _, op in ipairs(read_ops) do
- if read_yields then
- -- use Lua/C implmenetation
- index_mt[op] = index_mt[op .. "_luac"]
- else
- -- use FFI implementation
- index_mt[op] = index_mt[op .. "_ffi"]
- end
+ local index_mt
+ if space.engine == 'vinyl' then
+ index_mt = table.deepcopy(vinyl_index_mt)
+ else
+ index_mt = table.deepcopy(memtx_index_mt)
end
- index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility
- index_mt.__ipairs = index_mt.pairs -- Lua 5.2 compatibility
setmetatable(space, space_mt)
if type(space.index) == 'table' and space.enabled then
--
2.14.3 (Apple Git-98)
next prev parent reply other threads:[~2018-04-03 16:50 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-23 13:07 [PATCH 0/2] schema: expose space_mt and index_mt on table Vladislav Shpilevoy
2018-03-23 13:07 ` [PATCH 1/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy
2018-03-23 13:07 ` [PATCH 2/2] schema: review fixes for box.schema.space/index metatables Vladislav Shpilevoy
2018-03-29 10:54 ` [PATCH 0/2] schema: expose space_mt and index_mt on table Vladimir Davydov
2018-03-29 14:31 ` [PATCH v2 0/2] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy
2018-03-29 14:31 ` [PATCH v2 1/2] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy
2018-04-01 9:33 ` Vladimir Davydov
2018-04-01 11:02 ` [PATCH 0/2] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy
2018-04-01 11:02 ` [PATCH 1/2] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy
2018-04-01 11:02 ` [PATCH 2/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy
2018-04-02 11:28 ` Vladimir Davydov
2018-04-03 16:50 ` [PATCH v2 0/3] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy
2018-04-03 16:50 ` [PATCH v2 1/3] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy
2018-04-03 16:50 ` Vladislav Shpilevoy [this message]
2018-04-03 16:50 ` [PATCH v2 3/3] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy
2018-05-05 12:47 ` [tarantool-patches] " Vladislav Shpilevoy
2018-05-08 16:48 ` Konstantin Osipov
2018-05-08 17:33 ` Vladislav Shpilevoy
2018-03-29 14:31 ` [PATCH v2 2/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy
2018-04-01 9:37 ` [PATCH v2 0/2] schema: expose space_mt and index_mt on box.schema table Vladimir Davydov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d7fda3e42181f04fcbfa6e37a17f8b036dc4945e.1522774214.git.v.shpilevoy@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=tarantool-patches@freelists.org \
--cc=vdavydov.dev@gmail.com \
--subject='Re: [PATCH v2 2/3] schema: inherit vinyl/memtx_index_mt from base index mt' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox