Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement logarithmic index:count in the memtx tree #10139

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/box/index_def.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const struct index_opts index_opts_default = {
/* .lsn = */ 0,
/* .func = */ 0,
/* .hint = */ INDEX_HINT_DEFAULT,
/* .fast_offset = */ false,
};

/**
Expand Down Expand Up @@ -89,6 +90,7 @@ const struct opt_def index_opts_reg[] = {
OPT_DEF("func", OPT_UINT32, struct index_opts, func_id),
OPT_DEF_LEGACY("sql"),
OPT_DEF_CUSTOM("hint", index_opts_parse_hint),
OPT_DEF("fast_offset", OPT_BOOL, struct index_opts, fast_offset),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to keep the flag, let's enable it by default, as it was suggested in the design document.

OPT_END,
};

Expand Down
6 changes: 6 additions & 0 deletions src/box/index_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ struct index_opts {
* Use hint optimization for tree index.
*/
enum index_hint_cfg hint;
/**
* Use logarithmic select with offset.
*/
bool fast_offset;
};

extern const struct index_opts index_opts_default;
Expand Down Expand Up @@ -155,6 +159,8 @@ index_opts_cmp(const struct index_opts *o1, const struct index_opts *o2)
return o1->func_id - o2->func_id;
if (o1->hint != o2->hint)
return o1->hint - o2->hint;
if (o1->fast_offset != o2->fast_offset)
return o1->fast_offset - o2->fast_offset;
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions src/box/lua/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,7 @@ local index_options = {
bloom_fpr = 'number',
func = 'number, string',
hint = 'boolean',
fast_offset = 'boolean',
}

local function jsonpaths_from_idx_parts(parts)
Expand Down Expand Up @@ -1684,6 +1685,7 @@ box.schema.index.create = atomic_wrapper(function(space_id, name, options)
bloom_fpr = options.bloom_fpr,
func = options.func,
hint = options.hint,
fast_offset = options.fast_offset,
}
local field_type_aliases = {
num = 'unsigned'; -- Deprecated since 1.7.2
Expand Down
4 changes: 4 additions & 0 deletions src/box/lua/space.cc
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,13 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i)
if (space_is_memtx(space) && index_def->type == TREE) {
lua_pushboolean(L, index_opts->hint == INDEX_HINT_ON);
lua_setfield(L, -2, "hint");
lua_pushboolean(L, index_opts->fast_offset);
lua_setfield(L, -2, "fast_offset");
} else {
lua_pushnil(L);
lua_setfield(L, -2, "hint");
lua_pushnil(L);
lua_setfield(L, -2, "fast_offset");
}

if (index_opts->func_id > 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/box/memtx_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2014,6 +2014,8 @@ memtx_index_def_change_requires_rebuild(struct index *index,
return true;
if (old_def->opts.hint != new_def->opts.hint)
return true;
if (old_def->opts.fast_offset != new_def->opts.fast_offset)
return true;

const struct key_def *old_cmp_def, *new_cmp_def;
if (index_depends_on_pk(index)) {
Expand Down
84 changes: 37 additions & 47 deletions src/box/memtx_space.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,18 +782,6 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def)
"HASH index must be unique");
return -1;
}
if (key_def->is_multikey) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"HASH index cannot be multikey");
return -1;
}
if (key_def->for_func_index) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"HASH index can not use a function");
return -1;
}
break;
case TREE:
/* TREE index has no limitations. */
Expand All @@ -817,20 +805,7 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def)
"RTREE index field type must be ARRAY");
return -1;
}
if (key_def->is_multikey) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"RTREE index cannot be multikey");
return -1;
}
if (key_def->for_func_index) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"RTREE index can not use a function");
return -1;
}
/* no furter checks of parts needed */
return 0;
break;
case BITSET:
if (key_def->part_count != 1) {
diag_set(ClientError, ER_MODIFY_INDEX,
Expand All @@ -853,41 +828,56 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def)
"NUM or STR or VARBINARY");
return -1;
}
break;
default:
diag_set(ClientError, ER_INDEX_TYPE,
index_def->name, space_name(space));
return -1;
}

/* Some features are only supported by the TREE index. */
if (index_def->type != TREE) {
if (index_def->opts.hint == INDEX_HINT_ON &&
recovery_state == FINISHED_RECOVERY) {
/*
* The error is silenced during recovery to be able to
* recover the indexes with incorrect hint options.
*/
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
tt_sprintf("%s index does not support hints",
index_type_strs[index_def->type]));
return -1;
}
if (index_def->opts.fast_offset) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
tt_sprintf("%s index does not support the "
"accelerated select with offset",
index_type_strs[index_def->type]));
return -1;
}
if (key_def->is_multikey) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"BITSET index cannot be multikey");
tt_sprintf("%s index cannot be multikey",
index_type_strs[index_def->type]));
return -1;
}
if (key_def->for_func_index) {
diag_set(ClientError, ER_MODIFY_INDEX,
index_def->name, space_name(space),
"BITSET index can not use a function");
tt_sprintf("%s index can not use a function",
index_type_strs[index_def->type]));
return -1;
}
/* no furter checks of parts needed */
return 0;
default:
diag_set(ClientError, ER_INDEX_TYPE,
index_def->name, space_name(space));
return -1;
}

if (index_def->type != TREE && index_def->opts.hint == INDEX_HINT_ON &&
recovery_state == FINISHED_RECOVERY) {
/*
* The error is silenced during recovery to be able to recover
* the indexes with incorrect hint options.
*/
diag_set(ClientError, ER_MODIFY_INDEX, index_def->name,
space_name(space),
"hint is only reasonable with memtx tree index");
return -1;
}

/* Only HASH and TREE indexes check parts there. */
if (index_def_check_field_types(index_def, space_name(space)) != 0)
if ((index_def->type == TREE || index_def->type == HASH) &&
index_def_check_field_types(index_def, space_name(space)) != 0)
return -1;

return 0;
}

Expand Down
Loading
Loading