diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e7157a..9819b86e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Fixed +* drop wrap_box_space_func_result to cut allocations and speed up storage calls. + ## [1.6.1] - 19-09-25 ### Added diff --git a/crud/borders.lua b/crud/borders.lua index 96f70fa3..0c696698 100644 --- a/crud/borders.lua +++ b/crud/borders.lua @@ -36,11 +36,11 @@ local function get_border_on_storage(border_name, space_name, index_id, field_na return index[border_name](index) end - return schema.wrap_func_result(space, get_index_border, {index}, { + return schema.wrap_func_result(space, get_index_border, { add_space_schema_hash = true, field_names = field_names, fetch_latest_metadata = fetch_latest_metadata, - }) + }, index) end borders.storage_api = {[STAT_FUNC_NAME] = get_border_on_storage} diff --git a/crud/common/schema.lua b/crud/common/schema.lua index 4a2c3c37..5e7e7259 100644 --- a/crud/common/schema.lua +++ b/crud/common/schema.lua @@ -209,14 +209,18 @@ function schema.truncate_row_trailing_fields(tuple, field_names) return tuple end -function schema.wrap_func_result(space, func, args, opts) - dev_checks('table', 'function', 'table', 'table') +-- schema.wrap_func_result pcalls function +-- and returns its result as a table +-- `{res = ..., err = ..., space_schema_hash = ...}` +-- space_schema_hash is computed if function failed and +-- `add_space_schema_hash` is true +function schema.wrap_func_result(space, func, opts, ...) + dev_checks('table', 'function', 'table') + opts = opts or {} local result = {} - opts = opts or {} - - local ok, func_res = pcall(func, unpack(args)) + local ok, func_res = pcall(func, ...) if ok then if opts.noreturn ~= true then result.res = filter_tuple_fields(func_res, opts.field_names) @@ -246,20 +250,6 @@ function schema.wrap_func_result(space, func, args, opts) return result end --- schema.wrap_box_space_func_result pcalls some box.space function --- and returns its result as a table --- `{res = ..., err = ..., space_schema_hash = ...}` --- space_schema_hash is computed if function failed and --- `add_space_schema_hash` is true -function schema.wrap_box_space_func_result(space, box_space_func_name, box_space_func_args, opts) - dev_checks('table', 'string', 'table', 'table') - local function func(space, box_space_func_name, box_space_func_args) - return space[box_space_func_name](space, unpack(box_space_func_args)) - end - - return schema.wrap_func_result(space, func, {space, box_space_func_name, box_space_func_args}, opts) -end - -- schema.result_needs_reload checks that schema reload can -- be helpful to avoid storage error. -- It checks if space_schema_hash returned by storage diff --git a/crud/delete.lua b/crud/delete.lua index 6f15b9af..8cb5c412 100644 --- a/crud/delete.lua +++ b/crud/delete.lua @@ -44,12 +44,12 @@ local function delete_on_storage(space_name, key, field_names, opts) -- add_space_schema_hash is false because -- reloading space format on router can't avoid delete error on storage - return schema.wrap_box_space_func_result(space, 'delete', {key}, { + return schema.wrap_func_result(space, space.delete, { add_space_schema_hash = false, field_names = field_names, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, key) end delete.storage_api = {[DELETE_FUNC_NAME] = delete_on_storage} diff --git a/crud/get.lua b/crud/get.lua index feca57c5..8ddeca3d 100644 --- a/crud/get.lua +++ b/crud/get.lua @@ -43,11 +43,11 @@ local function get_on_storage(space_name, key, field_names, opts) -- add_space_schema_hash is false because -- reloading space format on router can't avoid get error on storage - return schema.wrap_box_space_func_result(space, 'get', {key}, { + return schema.wrap_func_result(space, space.get, { add_space_schema_hash = false, field_names = field_names, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, key) end get.storage_api = {[GET_FUNC_NAME] = get_on_storage} diff --git a/crud/insert.lua b/crud/insert.lua index ebb3f865..11288b5f 100644 --- a/crud/insert.lua +++ b/crud/insert.lua @@ -45,12 +45,12 @@ local function insert_on_storage(space_name, tuple, opts) -- add_space_schema_hash is true only in case of insert_object -- the only one case when reloading schema can avoid insert error -- is flattening object on router - return schema.wrap_box_space_func_result(space, 'insert', {tuple}, { + return schema.wrap_func_result(space, space.insert, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple) end insert.storage_api = {[INSERT_FUNC_NAME] = insert_on_storage} diff --git a/crud/insert_many.lua b/crud/insert_many.lua index f4299fd6..96616cee 100644 --- a/crud/insert_many.lua +++ b/crud/insert_many.lua @@ -57,12 +57,12 @@ local function insert_many_on_storage(space_name, tuples, opts) -- add_space_schema_hash is true only in case of insert_object_many -- the only one case when reloading schema can avoid insert error -- is flattening object on router - local insert_result = schema.wrap_box_space_func_result(space, 'insert', {tuple}, { + local insert_result = schema.wrap_func_result(space, space.insert, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple) if opts.fetch_latest_metadata then replica_schema_version = insert_result.storage_info.replica_schema_version end diff --git a/crud/replace.lua b/crud/replace.lua index 5e36906f..d2999d58 100644 --- a/crud/replace.lua +++ b/crud/replace.lua @@ -45,12 +45,14 @@ local function replace_on_storage(space_name, tuple, opts) -- add_space_schema_hash is true only in case of replace_object -- the only one case when reloading schema can avoid insert error -- is flattening object on router - return schema.wrap_box_space_func_result(space, 'replace', {tuple}, { + + local result = schema.wrap_func_result(space, space.replace, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple) + return result end replace.storage_api = {[REPLACE_FUNC_NAME] = replace_on_storage} diff --git a/crud/replace_many.lua b/crud/replace_many.lua index d047a3b0..18082a29 100644 --- a/crud/replace_many.lua +++ b/crud/replace_many.lua @@ -57,12 +57,12 @@ local function replace_many_on_storage(space_name, tuples, opts) -- add_space_schema_hash is true only in case of replace_object_many -- the only one case when reloading schema can avoid replace error -- is flattening object on router - local insert_result = schema.wrap_box_space_func_result(space, 'replace', {tuple}, { + local insert_result = schema.wrap_func_result(space, space.replace, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple) if opts.fetch_latest_metadata then replica_schema_version = insert_result.storage_info.replica_schema_version diff --git a/crud/update.lua b/crud/update.lua index 36ce242d..74a1fbc6 100644 --- a/crud/update.lua +++ b/crud/update.lua @@ -44,12 +44,12 @@ local function update_on_storage(space_name, key, operations, field_names, opts) -- add_space_schema_hash is false because -- reloading space format on router can't avoid update error on storage - local res, err = schema.wrap_box_space_func_result(space, 'update', {key, operations}, { + local res, err = schema.wrap_func_result(space, space.update, { add_space_schema_hash = false, field_names = field_names, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, key, operations) if err ~= nil then return nil, err @@ -66,12 +66,12 @@ local function update_on_storage(space_name, key, operations, field_names, opts) -- More details: https://github.com/tarantool/tarantool/issues/3378 if utils.is_field_not_found(res.err.code) then operations = utils.add_intermediate_nullable_fields(operations, space:format(), space:get(key)) - res, err = schema.wrap_box_space_func_result(space, 'update', {key, operations}, { + res, err = schema.wrap_func_result(space, space.update, { add_space_schema_hash = false, field_names = field_names, noreturn = opts.noreturn, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, key, operations) end return res, err diff --git a/crud/upsert.lua b/crud/upsert.lua index 5be7bc4a..09fdadbd 100644 --- a/crud/upsert.lua +++ b/crud/upsert.lua @@ -44,10 +44,10 @@ local function upsert_on_storage(space_name, tuple, operations, opts) -- add_space_schema_hash is true only in case of upsert_object -- the only one case when reloading schema can avoid insert error -- is flattening object on router - return schema.wrap_box_space_func_result(space, 'upsert', {tuple, operations}, { + return schema.wrap_func_result(space, space.upsert, { add_space_schema_hash = opts.add_space_schema_hash, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple, operations) end upsert.storage_api = {[UPSERT_FUNC_NAME] = upsert_on_storage} diff --git a/crud/upsert_many.lua b/crud/upsert_many.lua index f030e778..915868e8 100644 --- a/crud/upsert_many.lua +++ b/crud/upsert_many.lua @@ -56,10 +56,10 @@ local function upsert_many_on_storage(space_name, tuples, operations, opts) -- add_space_schema_hash is true only in case of upsert_object_many -- the only one case when reloading schema can avoid upsert error -- is flattening object on router - local insert_result = schema.wrap_box_space_func_result(space, 'upsert', {tuple, operations[i]}, { + local insert_result = schema.wrap_func_result(space, space.upsert, { add_space_schema_hash = opts.add_space_schema_hash, fetch_latest_metadata = opts.fetch_latest_metadata, - }) + }, space, tuple, operations[i]) if opts.fetch_latest_metadata then replica_schema_version = insert_result.storage_info.replica_schema_version end