From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [tarantool-patches] [PATCH v2 2/2] Fixed lost format on update and upsert operations. Date: Fri, 6 Apr 2018 19:24:42 +0300 [thread overview] Message-ID: <ae6f6cf2eaeb6598f20493e145ed006e89fb509e.1523031806.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1523031806.git.kshcherbatov@tarantool.org> In-Reply-To: <cover.1523031806.git.kshcherbatov@tarantool.org> Fixes #3051 --- src/box/lua/tuple.c | 4 ++- src/box/memtx_tuple.cc | 1 + src/box/tuple.c | 42 ++++++++++++++++-------- src/box/tuple.h | 6 +++- src/box/tuple_format.h | 5 ++- src/box/vy_stmt.c | 7 ++++ src/box/vy_stmt.h | 9 +++++ test/box/update.result | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ test/box/update.test.lua | 28 ++++++++++++++++ 9 files changed, 170 insertions(+), 17 deletions(-) diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c index 47b33c9..dffd5a5 100644 --- a/src/box/lua/tuple.c +++ b/src/box/lua/tuple.c @@ -36,6 +36,7 @@ #include <small/ibuf.h> #include <small/region.h> #include <fiber.h> +#include <box/tuple_update.h> #include "box/tuple.h" #include "box/tuple_convert.h" @@ -392,7 +393,8 @@ lbox_tuple_transform(struct lua_State *L) /* Execute tuple_update */ struct tuple *new_tuple = - box_tuple_update(tuple, buf->buf, buf->buf + ibuf_used(buf)); + box_tuple_update_ex(tuple, buf->buf, buf->buf + ibuf_used(buf), + box_tuple_format_default()); if (new_tuple == NULL) luaT_error(L); /* box_tuple_update() doesn't leak on exception, see public API doc */ diff --git a/src/box/memtx_tuple.cc b/src/box/memtx_tuple.cc index 70453bd..1990bdf 100644 --- a/src/box/memtx_tuple.cc +++ b/src/box/memtx_tuple.cc @@ -90,6 +90,7 @@ memtx_tuple_free(void) struct tuple_format_vtab memtx_tuple_format_vtab = { memtx_tuple_delete, + memtx_tuple_new, }; struct tuple * diff --git a/src/box/tuple.c b/src/box/tuple.c index d4760f3..ec2c3b5 100644 --- a/src/box/tuple.c +++ b/src/box/tuple.c @@ -61,15 +61,19 @@ struct tuple_format *tuple_format_runtime; static void runtime_tuple_delete(struct tuple_format *format, struct tuple *tuple); +struct tuple * +runtime_tuple_new(struct tuple_format *format, const char *data, const char *end); + /** A virtual method table for tuple_format_runtime */ static struct tuple_format_vtab tuple_format_runtime_vtab = { runtime_tuple_delete, + runtime_tuple_new, }; struct tuple * -tuple_new(struct tuple_format *format, const char *data, const char *end) +runtime_tuple_new(struct tuple_format *format, const char *data, const char *end) { - assert(format->vtab.destroy == tuple_format_runtime_vtab.destroy); + assert(format->vtab.tuple_delete == tuple_format_runtime_vtab.tuple_delete); mp_tuple_assert(data, end); size_t data_len = end - data; @@ -102,7 +106,7 @@ tuple_new(struct tuple_format *format, const char *data, const char *end) static void runtime_tuple_delete(struct tuple_format *format, struct tuple *tuple) { - assert(format->vtab.destroy == tuple_format_runtime_vtab.destroy); + assert(format->vtab.tuple_delete == tuple_format_runtime_vtab.tuple_delete); say_debug("%s(%p)", __func__, tuple); assert(tuple->refs == 0); size_t total = sizeof(struct tuple) + tuple_format_meta_size(format) + @@ -147,6 +151,12 @@ tuple_validate_raw(struct tuple_format *format, const char *tuple) return 0; } +struct tuple * +tuple_new(struct tuple_format *format, const char *data, const char *end) +{ + return format->vtab.tuple_new(format, data, end); +} + /** * Incremented on every snapshot and is used to distinguish tuples * which were created after start of a snapshot (these tuples can @@ -393,25 +403,23 @@ box_tuple_next(box_tuple_iterator_t *it) } box_tuple_t * -box_tuple_update(const box_tuple_t *tuple, const char *expr, - const char *expr_end) +box_tuple_update_ex(const box_tuple_t *tuple, const char *expr, + const char *expr_end, struct tuple_format *format) { - struct tuple_format *format = tuple_format_runtime; - uint32_t new_size = 0, bsize; const char *old_data = tuple_data_range(tuple, &bsize); struct region *region = &fiber()->gc; size_t used = region_used(region); const char *new_data = tuple_update_execute(region_aligned_alloc_cb, region, expr, - expr_end, old_data, old_data + bsize, - &new_size, 1, NULL); + expr_end, old_data, old_data + bsize, + &new_size, 1, NULL); if (new_data == NULL) { region_truncate(region, used); return NULL; } - - struct tuple *ret = tuple_new(format, new_data, new_data + new_size); + struct tuple *ret = tuple_new(format, new_data, + new_data + new_size); region_truncate(region, used); if (ret != NULL) return tuple_bless(ret); @@ -419,11 +427,16 @@ box_tuple_update(const box_tuple_t *tuple, const char *expr, } box_tuple_t * -box_tuple_upsert(const box_tuple_t *tuple, const char *expr, +box_tuple_update(const box_tuple_t *tuple, const char *expr, const char *expr_end) { - struct tuple_format *format = tuple_format_runtime; + return box_tuple_update_ex(tuple, expr, expr_end, tuple_format(tuple)); +} +box_tuple_t * +box_tuple_upsert(const box_tuple_t *tuple, const char *expr, + const char *expr_end) +{ uint32_t new_size = 0, bsize; const char *old_data = tuple_data_range(tuple, &bsize); struct region *region = &fiber()->gc; @@ -437,7 +450,8 @@ box_tuple_upsert(const box_tuple_t *tuple, const char *expr, return NULL; } - struct tuple *ret = tuple_new(format, new_data, new_data + new_size); + struct tuple *ret = tuple_new(tuple_format(tuple), + new_data, new_data + new_size); region_truncate(region, used); if (ret != NULL) return tuple_bless(ret); diff --git a/src/box/tuple.h b/src/box/tuple.h index 6ebedf5..d5b5bdb 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -282,6 +282,10 @@ box_tuple_update(const box_tuple_t *tuple, const char *expr, const char *expr_end); box_tuple_t * +box_tuple_update_ex(const box_tuple_t *tuple, const char *expr, + const char *expr_end, struct tuple_format *format); + +box_tuple_t * box_tuple_upsert(const box_tuple_t *tuple, const char *expr, const char *expr_end); @@ -445,7 +449,7 @@ tuple_delete(struct tuple *tuple) say_debug("%s(%p)", __func__, tuple); assert(tuple->refs == 0); struct tuple_format *format = tuple_format(tuple); - format->vtab.destroy(format, tuple); + format->vtab.tuple_delete(format, tuple); } /** diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h index d35182d..cc727ec 100644 --- a/src/box/tuple_format.h +++ b/src/box/tuple_format.h @@ -68,7 +68,10 @@ struct tuple_format; struct tuple_format_vtab { /** Free allocated tuple using engine-specific memory allocator. */ void - (*destroy)(struct tuple_format *format, struct tuple *tuple); + (*tuple_delete)(struct tuple_format *format, struct tuple *tuple); + /** Allocates a new tuple on the same allocator and with the same format. */ + struct tuple* + (*tuple_new)(struct tuple_format *format, const char *data, const char *end); }; /** Tuple field meta information for tuple_format. */ diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c index 84182e7..3135c58 100644 --- a/src/box/vy_stmt.c +++ b/src/box/vy_stmt.c @@ -47,6 +47,7 @@ struct tuple_format_vtab vy_tuple_format_vtab = { vy_tuple_delete, + vy_tuple_new, }; size_t vy_max_tuple_size = 1024 * 1024; @@ -69,6 +70,12 @@ vy_tuple_delete(struct tuple_format *format, struct tuple *tuple) free(tuple); } +struct tuple * +vy_tuple_new(struct tuple_format *format, const char *data, const char *end) +{ + return vy_stmt_new_insert(format, data, end); +} + /** * Allocate a vinyl statement object on base of the struct tuple * with malloc() and the reference counter equal to 1. diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h index a33739d..efc99c8 100644 --- a/src/box/vy_stmt.h +++ b/src/box/vy_stmt.h @@ -206,6 +206,15 @@ void vy_tuple_delete(struct tuple_format *format, struct tuple *tuple); /** + * Create the tuple of a vinyl space. + * @param format Target tuple format. + * @param data Target tuple data. + * @param size Size of the data. + */ +struct tuple * +vy_tuple_new(struct tuple_format *format, const char *data, const char *end); + +/** * Duplicate the statememnt. * * @param stmt statement diff --git a/test/box/update.result b/test/box/update.result index a3f731b..b8e94b1 100644 --- a/test/box/update.result +++ b/test/box/update.result @@ -849,3 +849,88 @@ s:update(1, {{'=', 3, map}}) s:drop() --- ... +format = {} +--- +... +format[1] = {name = 'KEY', type = 'unsigned'} +--- +... +format[2] = {name = 'VAL', type = 'string'} +--- +... +s = box.schema.create_space('tst_sample', {format = format}) +--- +... +pk = s:create_index('pk') +--- +... +s:insert({1, 'sss'}) +--- +- [1, 'sss'] +... +aa = box.space.tst_sample:get(1) +--- +... +aa.VAL +--- +- sss +... +aa = aa:update({{'=',2,'ssss'}}) +--- +... +collectgarbage() +--- +- 0 +... +aa.VAL +--- +- ssss +... +s:drop() +--- +... +aa = nil +--- +... +collectgarbage() +--- +- 0 +... +s = box.schema.space.create('tst_sample', {engine = 'vinyl', format = format}) +--- +... +pk = s:create_index('pk') +--- +... +s:insert({1, 'sss'}) +--- +- [1, 'sss'] +... +aa = box.space.tst_sample:get(1) +--- +... +aa.VAL +--- +- sss +... +aa = aa:update({{'=',2,'ssss'}}) +--- +... +collectgarbage() +--- +- 0 +... +aa.VAL +--- +- ssss +... +s:drop() +--- +... +aa = nil +--- +... +collectgarbage() +--- +- 0 +... diff --git a/test/box/update.test.lua b/test/box/update.test.lua index c455bc1..37be3a0 100644 --- a/test/box/update.test.lua +++ b/test/box/update.test.lua @@ -269,3 +269,31 @@ t:update({{'=', 3, map}}) s:update(1, {{'=', 3, map}}) s:drop() + + +format = {} +format[1] = {name = 'KEY', type = 'unsigned'} +format[2] = {name = 'VAL', type = 'string'} +s = box.schema.create_space('tst_sample', {format = format}) +pk = s:create_index('pk') +s:insert({1, 'sss'}) +aa = box.space.tst_sample:get(1) +aa.VAL +aa = aa:update({{'=',2,'ssss'}}) +collectgarbage() +aa.VAL +s:drop() +aa = nil +collectgarbage() + +s = box.schema.space.create('tst_sample', {engine = 'vinyl', format = format}) +pk = s:create_index('pk') +s:insert({1, 'sss'}) +aa = box.space.tst_sample:get(1) +aa.VAL +aa = aa:update({{'=',2,'ssss'}}) +collectgarbage() +aa.VAL +s:drop() +aa = nil +collectgarbage() -- 2.7.4
next prev parent reply other threads:[~2018-04-06 16:24 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-04-06 16:24 [tarantool-patches] [PATCH v2 0/2] Fix lost format on update operation Kirill Shcherbatov 2018-04-06 16:24 ` [tarantool-patches] [PATCH v2 1/2] Fixed invalid check in lbox_tuple_transform Kirill Shcherbatov 2018-04-06 16:24 ` Kirill Shcherbatov [this message] 2018-04-08 13:56 ` [tarantool-patches] Re: [PATCH v2 2/2] Fixed lost format on update and upsert operations Vladislav Shpilevoy 2018-04-10 10:23 ` Kirill Shcherbatov 2018-04-10 10:44 ` Vladislav Shpilevoy 2018-04-15 10:03 ` Kirill Shcherbatov 2018-04-15 13:18 ` Vladislav Shpilevoy 2018-04-16 7:47 ` Kirill Shcherbatov 2018-04-16 10:07 ` Vladislav Shpilevoy 2018-04-16 16:51 ` Kirill Shcherbatov 2018-04-16 17:14 ` Vladislav Shpilevoy 2018-04-18 12:28 ` Vladimir Davydov 2018-04-18 12:55 ` Kirill Shcherbatov 2018-04-22 15:15 ` Vladislav Shpilevoy 2018-04-28 6:56 ` Kirill Shcherbatov 2018-04-28 9:29 ` [tarantool-patches] Re: [PATCH v2 0/2] Fix lost format on update operation Vladislav Shpilevoy
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=ae6f6cf2eaeb6598f20493e145ed006e89fb509e.1523031806.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH v2 2/2] Fixed lost format on update and upsert operations.' \ /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