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