My solution.
I separated creation logic and implemented iterator based on closures.
lua box.space[0].index[0]:tuples(flags) returns function (closure) which will
return next value from the index on each call.
flags is abstraction on struct iterator_type {}. I want to add more options
which will define iterator behaviour, for example
enum iterator_flags {
/* :2 bits, direction */
ITER_FORWARD = 0x0, /* forward direction */
ITER_REVERSE = 0x1, /* backward direction */
/* :6 bits, match type */
ITER_EXACT = 0x0 << 2, /* exact match, key = x, arguments
must be keys */
ITER_EXPR = 0x1 << 2, /* x is index-dependent expression,
argument must be expression */
....
ITER_BITS_ALL_SET = 0x5 << 2 /* other match types */
}
Without key, with flags = ITER_FORWARD | ITER_EXACT
localhost> lua iter = box.space[0].index[0]:tuples(flags);
---
...
localhost> lua print(iter());
---
2: {1}
...
localhost> lua print(iter());
---
2: {3}
...
localhost> lua print(iter());
---
2: {4}
...
localhost> lua print(iter());
---
2: {5}
...
localhost> lua print(iter());
Similar for ITER_REVERSE.
With start key (multi-part):
localhost> lua iter = box.space[0].index[0]:tuples(flags, 2, 3);
---
...
localhost> lua print(iter());
---
2: {3}
...
localhost> lua print(iter());
---
2: {4}
...
localhost> lua print(iter());
---
2: {5}
...
localhost> lua print(iter());
This API can be easilly extended in order to support custom expressions
and custom comparison logic.
index.next and index.prev could be easilly implemented using this method
as backend.
--
You received this bug notification because you are a member of Tarantool
Development Team, which is subscribed to tarantool.
https://bugs.launchpad.net/bugs/1073476
Title:
box.select_range and box.select_reverse_range only use first part of
compound keys / index.next API is weird
Status in Tarantool - an efficient in-memory data store:
New
Bug description:
This bug is related to
https://bugs.launchpad.net/tarantool/+bug/1073457 , but have another
roots of the problem.
space[0].enabled = 1
space[0].index[0].type = "TREE"
space[0].index[0].unique = 1
space[0].index[0].key_field[0].fieldno = 0
space[0].index[0].key_field[0].type = "NUM"
space[0].index[0].key_field[1].fieldno = 1
space[0].index[0].key_field[1].type = "NUM"
INSERT INTO t0 VALUES(2,1)
INSERT INTO t0 VALUES(2,3)
INSERT INTO t0 VALUES(2,4)
INSERT INTO t0 VALUES(2,5)
INSERT INTO t0 VALUES(2,6)
INSERT INTO t0 VALUES(2,7)
INSERT INTO t0 VALUES(2,8)
localhost> lua box.select_range(0, 0, 100, 2)
---
- 2: {1}
- 2: {3}
- 2: {4}
- 2: {5}
- 2: {6}
- 2: {7}
- 2: {8}
Incorrect, works like box.select bug (see
https://bugs.launchpad.net/tarantool/+bug/1073457).
localhost> lua box.select_range(0, 0, 100, 2, 3)
---
- 2: {1}
- 2: {3}
- 2: {4}
- 2: {5}
- 2: {6}
- 2: {7}
- 2: {8}
Also incorrect, should select entries starting from 2: {3} (box.select
works properly).
box.select_range and box.select_reverse_range are implemented entirely
in Lua, based on box.index methods.
01 index_mt.select_range = function(index, limit, ...)
02 local range = {}
03 for k, v in index.idx.next, index.idx, ... do
04 if #range >= limit then
05 break
06 end
07 table.insert(range, v)
08 end
09 return unpack(range)
10 end
I am not Lua guru, but seems that expression in line 10 with params like
"box.select_range(space_no, index_no, key0, key1, key2)" will be expanded to
"for k, v in index.idx.next, index.idx, key0, key1, key2 do".
According to lua manual, a for statement like
for var_1, ···, var_n in explist do block end
is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
var = var_1
if var == nil then break end
block
end
end
for our case "for" is evaluated like this
"local f, s, var = index.idx.next, index.idx, key0, key1, key2"
As result, all keys begin from second will be ignored.
I have no idea how to fix it, because current the index iteration API is
definetly weird (will post another bug for that).
To manage notifications about this bug go to:
https://bugs.launchpad.net/tarantool/+bug/1073476/+subscriptions
_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help : https://help.launchpad.net/ListHelp