From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Kirill Shcherbatov Subject: [PATCH v4 1/4] box: introduce tuple_chunk infrastructure Date: Wed, 24 Jul 2019 10:36:07 +0300 Message-Id: <6018ccf411d14cf95cbd0e06a8c1eaa06a5c281e.1563953154.git.kshcherbatov@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit To: tarantool-patches@freelists.org, kostja@tarantool.org Cc: vdavydov.dev@gmail.com, Kirill Shcherbatov List-ID: Introduced a new object tuple_chunk: a memory allocation is associated with given tuple. tuple_format's vtab is extended with few new methods to manage tuple_chunks lifecycle. Implemented corresponding methid for memtx engine: a memory chunks are allocated with memtx's smalloc allocator. Needed for #1260 --- src/box/tuple.h | 28 ++++++++++++++++++++++++++++ src/box/tuple_format.h | 9 +++++++++ src/box/memtx_engine.c | 27 +++++++++++++++++++++++++++ src/box/tuple.c | 8 ++++++++ src/box/vy_stmt.c | 2 ++ 5 files changed, 74 insertions(+) diff --git a/src/box/tuple.h b/src/box/tuple.h index 99dfeb82d..60b6fb474 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -447,6 +447,34 @@ tuple_delete(struct tuple *tuple) format->vtab.tuple_delete(format, tuple); } +/** Tuple chunk memory object. */ +struct tuple_chunk { + /** The payload size. Needed to perform memory release.*/ + uint32_t data_sz; + /** Metadata object payload. */ + char data[0]; +}; + +/** Calculate the size of tuple_chunk object by given data_sz. */ +uint32_t +tuple_chunk_sz(uint32_t data_sz); + +/** Allocate a new tuple_chunk for given tuple. */ +static inline struct tuple_chunk * +tuple_chunk_new(struct tuple *tuple, uint32_t data_sz) +{ + struct tuple_format *format = tuple_format(tuple); + return format->vtab.tuple_chunk_new(format, tuple, data_sz); +} + +/** Free a tuple_chunk is allocated for given tuple. */ +static inline void +tuple_chunk_delete(struct tuple *tuple, struct tuple_chunk *tuple_chunk) +{ + struct tuple_format *format = tuple_format(tuple); + format->vtab.tuple_chunk_delete(format, tuple_chunk); +} + /** * Check tuple data correspondence to space format. * Actually, checks everything that is checked by diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h index e4f5f0018..63efbde04 100644 --- a/src/box/tuple_format.h +++ b/src/box/tuple_format.h @@ -64,6 +64,7 @@ enum { TUPLE_INDEX_BASE = 1 }; enum { TUPLE_OFFSET_SLOT_NIL = INT32_MAX }; struct tuple; +struct tuple_chunk; struct tuple_format; struct coll; @@ -82,6 +83,14 @@ struct tuple_format_vtab { struct tuple* (*tuple_new)(struct tuple_format *format, const char *data, const char *end); + /** Free a tuple_chunk allocated for given tuple. */ + void + (*tuple_chunk_delete)(struct tuple_format *format, + struct tuple_chunk *tuple_chunk); + /** Allocate a new tuple_chunk for given tuple. */ + struct tuple_chunk * + (*tuple_chunk_new)(struct tuple_format *format, struct tuple *tuple, + uint32_t data_sz); }; /** Tuple field meta information for tuple_format. */ diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c index 428491c2d..fbb3151c9 100644 --- a/src/box/memtx_engine.c +++ b/src/box/memtx_engine.c @@ -1126,9 +1126,36 @@ memtx_tuple_delete(struct tuple_format *format, struct tuple *tuple) smfree_delayed(&memtx->alloc, memtx_tuple, total); } +void +metmx_tuple_chunk_delete(struct tuple_format *format, + struct tuple_chunk *tuple_chunk) +{ + struct memtx_engine *memtx = (struct memtx_engine *)format->engine; + uint32_t sz = tuple_chunk_sz(tuple_chunk->data_sz); + smfree(&memtx->alloc, tuple_chunk, sz); +} + +struct tuple_chunk * +memtx_tuple_chunk_new(struct tuple_format *format, struct tuple *tuple, + uint32_t data_sz) +{ + struct memtx_engine *memtx = (struct memtx_engine *)format->engine; + uint32_t sz = tuple_chunk_sz(data_sz); + struct tuple_chunk *tuple_chunk = + (struct tuple_chunk *) smalloc(&memtx->alloc, sz); + if (tuple == NULL) { + diag_set(OutOfMemory, sz, "smalloc", "tuple"); + return NULL; + } + tuple_chunk->data_sz = data_sz; + return tuple_chunk; +} + struct tuple_format_vtab memtx_tuple_format_vtab = { memtx_tuple_delete, memtx_tuple_new, + metmx_tuple_chunk_delete, + memtx_tuple_chunk_new, }; /** diff --git a/src/box/tuple.c b/src/box/tuple.c index c0e94d55b..25f85f732 100644 --- a/src/box/tuple.c +++ b/src/box/tuple.c @@ -67,6 +67,8 @@ runtime_tuple_new(struct tuple_format *format, const char *data, const char *end static struct tuple_format_vtab tuple_format_runtime_vtab = { runtime_tuple_delete, runtime_tuple_new, + NULL, + NULL, }; static struct tuple * @@ -785,3 +787,9 @@ mp_str(const char *data) return ""; return buf; } + +uint32_t +tuple_chunk_sz(uint32_t data_sz) +{ + return sizeof(struct tuple_chunk) + data_sz; +} diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c index f936cd61f..518a24f43 100644 --- a/src/box/vy_stmt.c +++ b/src/box/vy_stmt.c @@ -118,6 +118,8 @@ vy_stmt_env_create(struct vy_stmt_env *env) { env->tuple_format_vtab.tuple_new = vy_tuple_new; env->tuple_format_vtab.tuple_delete = vy_tuple_delete; + env->tuple_format_vtab.tuple_chunk_new = NULL; + env->tuple_format_vtab.tuple_chunk_delete = NULL; env->max_tuple_size = 1024 * 1024; env->key_format = vy_stmt_format_new(env, NULL, 0, NULL, 0, 0, NULL); if (env->key_format == NULL) -- 2.22.0