Tarantool development patches archive
 help / color / mirror / Atom feed
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)

  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