Skip to content

Commit ab24dfb

Browse files
Gumixalyapunov
authored andcommitted
box: introduce tuple:info()
See the doc bot request for the description. Part of #6762 NO_CHANGELOG=next commit @TarantoolBot document Title: Document `tuple:info()` Product: Tarantool Since: 3.0 Root document: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_tuple/ tuple_object:info() - Get information about the tuple Returns a table with the following fields: * data_size - Size of the MessagePack data in the tuple. This number equals to number returned by `tuple_object:bsize()`. * header_size - Size of the internal tuple header. * field_map_size - Size of the field map. Field map is used to speed up access to indexed fields of the tuple. * waste_size - The amount of excess memory used to store the tuple in mempool. * arena - Type of the arena where the tuple is allocated. Possible values are: "memtx", "malloc", "runtime".
1 parent 3a3890e commit ab24dfb

File tree

11 files changed

+323
-2
lines changed

11 files changed

+323
-2
lines changed

src/box/allocator.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ class SmallAlloc
129129
{
130130
return &small_alloc;
131131
}
132+
static inline void
133+
get_alloc_info(void *ptr, size_t size, struct small_alloc_info *info)
134+
{
135+
small_alloc_info(&small_alloc, ptr, size, info);
136+
}
132137
private:
133138
static struct small_alloc small_alloc;
134139
};

src/box/lua/tuple.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,41 @@ luaT_pushtuple(struct lua_State *L, box_tuple_t *tuple)
722722
luaL_setcdatagc(L, -2);
723723
}
724724

725+
/**
726+
* Push to Lua stack a table with the information about a tuple, located on top
727+
* of the stack.
728+
*/
729+
static int
730+
lbox_tuple_info(lua_State *L)
731+
{
732+
int argc = lua_gettop(L);
733+
if (argc != 1)
734+
luaL_error(L, "Usage: tuple:info()");
735+
736+
struct tuple *tuple = luaT_checktuple(L, 1);
737+
struct tuple_info info;
738+
tuple_info(tuple, &info);
739+
740+
lua_newtable(L);
741+
742+
lua_pushnumber(L, info.data_size);
743+
lua_setfield(L, -2, "data_size");
744+
745+
lua_pushnumber(L, info.header_size);
746+
lua_setfield(L, -2, "header_size");
747+
748+
lua_pushnumber(L, info.field_map_size);
749+
lua_setfield(L, -2, "field_map_size");
750+
751+
lua_pushnumber(L, info.waste_size);
752+
lua_setfield(L, -2, "waste_size");
753+
754+
lua_pushstring(L, tuple_arena_type_strs[info.arena_type]);
755+
lua_setfield(L, -2, "arena");
756+
757+
return 1;
758+
}
759+
725760
static const struct luaL_Reg lbox_tuple_meta[] = {
726761
{"__gc", lbox_tuple_gc},
727762
{"tostring", lbox_tuple_to_string},
@@ -730,6 +765,7 @@ static const struct luaL_Reg lbox_tuple_meta[] = {
730765
{"tuple_to_map", lbox_tuple_to_map},
731766
{"tuple_field_by_path", lbox_tuple_field_by_path},
732767
{"new", lbox_tuple_new},
768+
{"info", lbox_tuple_info},
733769
{NULL, NULL}
734770
};
735771

src/box/lua/tuple.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ local methods = {
333333
["upsert"] = tuple_upsert;
334334
["bsize"] = tuple_bsize;
335335
["tomap"] = internal.tuple.tuple_to_map;
336+
["info"] = internal.tuple.info;
336337
}
337338

338339
-- Aliases for tuple:methods().

src/box/memtx_engine.cc

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1881,14 +1881,60 @@ memtx_tuple_delete(struct tuple_format *format, struct tuple *tuple)
18811881
tuple_format_unref(format);
18821882
}
18831883

1884+
/** Fill `info' with the information about the `tuple'. */
1885+
template<class ALLOC>
1886+
static inline void
1887+
memtx_tuple_info(struct tuple_format *format, struct tuple *tuple,
1888+
struct tuple_info *info);
1889+
1890+
template<>
1891+
inline void
1892+
memtx_tuple_info<SmallAlloc>(struct tuple_format *format, struct tuple *tuple,
1893+
struct tuple_info *info)
1894+
{
1895+
(void)format;
1896+
size_t size = tuple_size(tuple);
1897+
struct small_alloc_info alloc_info;
1898+
SmallAlloc::get_alloc_info(tuple, size, &alloc_info);
1899+
1900+
info->data_size = tuple_bsize(tuple);
1901+
info->header_size = sizeof(struct tuple);
1902+
if (tuple_is_compact(tuple))
1903+
info->header_size -= TUPLE_COMPACT_SAVINGS;
1904+
info->field_map_size = tuple_data_offset(tuple) - info->header_size;
1905+
if (alloc_info.is_large) {
1906+
info->waste_size = 0;
1907+
info->arena_type = TUPLE_ARENA_MALLOC;
1908+
} else {
1909+
info->waste_size = alloc_info.real_size - size;
1910+
info->arena_type = TUPLE_ARENA_MEMTX;
1911+
}
1912+
}
1913+
1914+
template<>
1915+
inline void
1916+
memtx_tuple_info<SysAlloc>(struct tuple_format *format, struct tuple *tuple,
1917+
struct tuple_info *info)
1918+
{
1919+
(void)format;
1920+
info->data_size = tuple_bsize(tuple);
1921+
info->header_size = sizeof(struct tuple);
1922+
if (tuple_is_compact(tuple))
1923+
info->header_size -= TUPLE_COMPACT_SAVINGS;
1924+
info->field_map_size = tuple_data_offset(tuple) - info->header_size;
1925+
info->waste_size = 0;
1926+
info->arena_type = TUPLE_ARENA_MALLOC;
1927+
}
1928+
18841929
struct tuple_format_vtab memtx_tuple_format_vtab;
18851930

1886-
template <class ALLOC>
1931+
template<class ALLOC>
18871932
static inline void
18881933
create_memtx_tuple_format_vtab(struct tuple_format_vtab *vtab)
18891934
{
18901935
vtab->tuple_delete = memtx_tuple_delete<ALLOC>;
18911936
vtab->tuple_new = memtx_tuple_new<ALLOC>;
1937+
vtab->tuple_info = memtx_tuple_info<ALLOC>;
18921938
}
18931939

18941940
/**

src/box/tuple.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ enum {
4646
OBJSIZE_MIN = 16,
4747
};
4848

49+
const char *tuple_arena_type_strs[tuple_arena_type_MAX] = {
50+
[TUPLE_ARENA_MEMTX] = "memtx",
51+
[TUPLE_ARENA_MALLOC] = "malloc",
52+
[TUPLE_ARENA_RUNTIME] = "runtime",
53+
};
54+
4955
/**
5056
* Storage for additional reference counter of a tuple.
5157
*/
@@ -93,10 +99,16 @@ runtime_tuple_delete(struct tuple_format *format, struct tuple *tuple);
9399
static struct tuple *
94100
runtime_tuple_new(struct tuple_format *format, const char *data, const char *end);
95101

102+
/** Fill `tuple_info'. */
103+
static void
104+
runtime_tuple_info(struct tuple_format *format, struct tuple *tuple,
105+
struct tuple_info *tuple_info);
106+
96107
/** A virtual method table for tuple_format_runtime */
97108
static struct tuple_format_vtab tuple_format_runtime_vtab = {
98109
runtime_tuple_delete,
99110
runtime_tuple_new,
111+
runtime_tuple_info,
100112
};
101113

102114
static struct tuple *
@@ -152,6 +164,24 @@ runtime_tuple_delete(struct tuple_format *format, struct tuple *tuple)
152164
smfree(&runtime_alloc, tuple, total);
153165
}
154166

167+
static void
168+
runtime_tuple_info(struct tuple_format *format, struct tuple *tuple,
169+
struct tuple_info *tuple_info)
170+
{
171+
assert(format->vtab.tuple_delete ==
172+
tuple_format_runtime_vtab.tuple_delete);
173+
(void)format;
174+
175+
uint16_t data_offset = tuple_data_offset(tuple);
176+
tuple_info->data_size = tuple_bsize(tuple);
177+
tuple_info->header_size = sizeof(struct tuple);
178+
if (tuple_is_compact(tuple))
179+
tuple_info->header_size -= TUPLE_COMPACT_SAVINGS;
180+
tuple_info->field_map_size = data_offset - tuple_info->header_size;
181+
tuple_info->waste_size = 0;
182+
tuple_info->arena_type = TUPLE_ARENA_RUNTIME;
183+
}
184+
155185
int
156186
tuple_validate_raw(struct tuple_format *format, const char *tuple)
157187
{

src/box/tuple.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,44 @@ struct PACKED tuple
459459

460460
static_assert(sizeof(struct tuple) == 10, "Just to be sure");
461461

462+
/** Type of the arena where the tuple is allocated. */
463+
enum tuple_arena_type {
464+
TUPLE_ARENA_MEMTX = 0,
465+
TUPLE_ARENA_MALLOC = 1,
466+
TUPLE_ARENA_RUNTIME = 2,
467+
tuple_arena_type_MAX
468+
};
469+
470+
/** Arena type names. */
471+
extern const char *tuple_arena_type_strs[tuple_arena_type_MAX];
472+
473+
/** Information about the tuple. */
474+
struct tuple_info {
475+
/** Size of the MsgPack data. See also tuple_bsize(). */
476+
size_t data_size;
477+
/** Header size depends on the engine and on the compact/bulky mode. */
478+
size_t header_size;
479+
/** Size of the field_map. See also field_map_build_size(). */
480+
size_t field_map_size;
481+
/**
482+
* The amount of excess memory used to store the tuple in mempool.
483+
* Note that this value is calculated not during the actual allocation,
484+
* but afterwards. This means that it can be incorrect if the state of
485+
* the allocator changed. See also small_alloc_info().
486+
*/
487+
size_t waste_size;
488+
/** Type of the arena where the tuple is allocated. */
489+
enum tuple_arena_type arena_type;
490+
};
491+
492+
/** Fill `info' with the information about the `tuple'. */
493+
static inline void
494+
tuple_info(struct tuple *tuple, struct tuple_info *info)
495+
{
496+
struct tuple_format *format = tuple_format_by_id(tuple->format_id);
497+
format->vtab.tuple_info(format, tuple, info);
498+
}
499+
462500
static_assert(DIV_ROUND_UP(tuple_flag_MAX, 8) <=
463501
sizeof(((struct tuple *)0)->flags),
464502
"enum tuple_flag doesn't fit into tuple->flags");

src/box/tuple_format.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ enum { TUPLE_INDEX_BASE = 1 };
6666
enum { TUPLE_OFFSET_SLOT_NIL = INT32_MAX };
6767

6868
struct tuple;
69+
struct tuple_info;
6970
struct tuple_format;
7071
struct coll;
7172
struct Expr;
@@ -104,6 +105,13 @@ struct tuple_format_vtab {
104105
struct tuple*
105106
(*tuple_new)(struct tuple_format *format, const char *data,
106107
const char *end);
108+
/**
109+
* Fill `tuple_info' with the engine-specific and allocator-specific
110+
* information about the `tuple'.
111+
*/
112+
void
113+
(*tuple_info)(struct tuple_format *format, struct tuple *tuple,
114+
struct tuple_info *tuple_info);
107115
};
108116

109117
struct tuple_constraint;

src/box/vy_stmt.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,26 @@ vy_tuple_delete(struct tuple_format *format, struct tuple *tuple)
119119
free(tuple);
120120
}
121121

122+
/** Fill `tuple_info'. */
123+
static void
124+
vy_tuple_info(struct tuple_format *format, struct tuple *tuple,
125+
struct tuple_info *tuple_info)
126+
{
127+
(void)format;
128+
uint16_t data_offset = tuple_data_offset(tuple);
129+
tuple_info->data_size = tuple_bsize(tuple);
130+
tuple_info->header_size = sizeof(struct vy_stmt);
131+
tuple_info->field_map_size = data_offset - tuple_info->header_size;
132+
tuple_info->waste_size = 0;
133+
tuple_info->arena_type = TUPLE_ARENA_MALLOC;
134+
}
135+
122136
void
123137
vy_stmt_env_create(struct vy_stmt_env *env)
124138
{
125139
env->tuple_format_vtab.tuple_new = vy_tuple_new;
126140
env->tuple_format_vtab.tuple_delete = vy_tuple_delete;
141+
env->tuple_format_vtab.tuple_info = vy_tuple_info;
127142
env->max_tuple_size = 1024 * 1024;
128143
env->sum_tuple_size = 0;
129144
env->key_format = vy_simple_stmt_format_new(env, NULL, 0);

0 commit comments

Comments
 (0)