Skip to content

Commit

Permalink
box: introduce the fast_offset index option
Browse files Browse the repository at this point in the history
This commit introduces a new `fast_offset` option of index. It means
to enable the acceleration of select with offset in an index if it
supports that (currently none of indexes do).

NO_DOC=see the next commit
NO_CHANGELOG=see the next commit
  • Loading branch information
mkostoevr committed Jun 15, 2024
1 parent e51d117 commit 31131f0
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 0 deletions.
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),
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 @@ -1487,6 +1487,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 @@ -1629,6 +1630,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
3 changes: 3 additions & 0 deletions src/box/lua/space.cc
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i)
lua_setfield(L, -2, "hint");
}

lua_pushnil(L);
lua_setfield(L, -2, "fast_offset");

if (index_opts->func_id > 0) {
lua_pushstring(L, "func");
lua_newtable(L);
Expand Down
5 changes: 5 additions & 0 deletions src/box/memtx_space.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,11 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def)
{
struct key_def *key_def = index_def->key_def;

if (index_def->opts.fast_offset) {
diag_set(ClientError, ER_UNSUPPORTED, "memtx",
"logarithmic select with offset");
return -1;
}
if (key_def->is_nullable) {
if (index_def->iid == 0) {
diag_set(ClientError, ER_NULLABLE_PRIMARY,
Expand Down
5 changes: 5 additions & 0 deletions src/box/vinyl.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,11 @@ vinyl_space_check_index_def(struct space *space, struct index_def *index_def)
"hint is only reasonable with memtx tree index");
return -1;
}
if (index_def->opts.fast_offset) {
diag_set(ClientError, ER_UNSUPPORTED, "Vinyl",
"logarithmic select with offset");
return -1;
}

struct key_def *key_def = index_def->key_def;

Expand Down
54 changes: 54 additions & 0 deletions test/box-luatest/gh_8204_fast_offset_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
local server = require('luatest.server')
local t = require('luatest')

local g = t.group()

g.before_all(function()
g.server = server:new({alias = 'master'})
g.server:start()
end)

g.after_all(function()
g.server:drop()
end)

g.after_each(function()
g.server:exec(function()
if box.space.test then
box.space.test:drop()
end
end)
end)

g.test_option = function()
g.server:exec(function()
local s = box.schema.space.create('test', {engine = 'memtx'})

-- Memtx does not support the fast_offset option.
t.assert_error_msg_content_equals(
"memtx does not support logarithmic select with offset",
s.create_index, s, 'pk', {fast_offset = true})

-- Can successfully create all indexes with fast_offset = false.
s:create_index('k0', {type = 'TREE', fast_offset = false})
s:create_index('k1', {type = 'HASH', fast_offset = false})
s:create_index('k2', {type = 'RTREE', fast_offset = false,
unique = false, parts = {2, 'array'}})
s:create_index('k3', {type = 'BITSET', fast_offset = false,
unique = false})

s:drop()

s = box.schema.space.create('test', {engine = 'vinyl'})

-- Vinyl does not support the fast_offset option.
t.assert_error_msg_content_equals(
"Vinyl does not support logarithmic select with offset",
s.create_index, s, 'pk', {fast_offset = true})

-- Can successfully create vinyl index with fast_offset = false.
s:create_index('pk', {fast_offset = false})

s:drop()
end)
end

0 comments on commit 31131f0

Please sign in to comment.