diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c index 428491c2d8421a9d3daf4370964a44d61882e1f2..91c0a7b1710a8972ea3f5f1b08b96c59f700c142 100644 --- a/src/box/memtx_engine.c +++ b/src/box/memtx_engine.c @@ -1126,9 +1126,39 @@ 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, const char *data) +{ + struct memtx_engine *memtx = (struct memtx_engine *)format->engine; + struct tuple_chunk *tuple_chunk = + container_of((typeof(tuple_chunk->data) *)data, + struct tuple_chunk, data); + uint32_t sz = tuple_chunk_sz(tuple_chunk->data_sz); + smfree(&memtx->alloc, tuple_chunk, sz); +} + +const char * +memtx_tuple_chunk_new(struct tuple_format *format, struct tuple *tuple, + const char *data, 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; + memcpy(tuple_chunk->data, data, data_sz); + return tuple_chunk->data; +} + 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 c0e94d55b6ac2cbf691bee6bd668e1b20da9ebdd..a01646c688bcad711a810fab1b94f0d2dc912c6d 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 * diff --git a/src/box/tuple.h b/src/box/tuple.h index 99dfeb82df8dd46f9fde45b2499d9ff30abe102d..4c4050ca8efdb81609e4152a91d2c691bd701435 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -447,6 +447,40 @@ 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. */ +static inline uint32_t +tuple_chunk_sz(uint32_t data_sz) +{ + return sizeof(struct tuple_chunk) + data_sz; +} + +/** + * Allocate a new tuple_chunk for given tuple and data and + * return a pointer to it's payload section. + */ +static inline const char * +tuple_chunk_new(struct tuple *tuple, const char *data, uint32_t data_sz) +{ + struct tuple_format *format = tuple_format(tuple); + return format->vtab.tuple_chunk_new(format, tuple, data, data_sz); +} + +/** Free a tuple_chunk allocated for given tuple and data. */ +static inline void +tuple_chunk_delete(struct tuple *tuple, const char *data) +{ + struct tuple_format *format = tuple_format(tuple); + format->vtab.tuple_chunk_delete(format, data); +} + /** * 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 e4f5f001863e86a66ba532b50401ab88451e724f..021072d3d4c7e83c6d923e2f6272dcd93aa7b0e3 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,20 @@ 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 and + * data. + */ + void + (*tuple_chunk_delete)(struct tuple_format *format, + const char *data); + /** + * Allocate a new tuple_chunk for given tuple and data and + * return a pointer to it's data section. + */ + const char * + (*tuple_chunk_new)(struct tuple_format *format, struct tuple *tuple, + const char *data, uint32_t data_sz); }; /** Tuple field meta information for tuple_format. */ diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c index f936cd61f83dcce17dec0f407449bd6e41be3354..518a24f43d7048acc439c4e6872e1552a652b1b9 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)