Skip to content
Snippets Groups Projects
Commit f2a5961b authored by Alexandr Lyapunov's avatar Alexandr Lyapunov Committed by Roman Tsisyk
Browse files

bitset: remove harmful optimization from index:count()

Fixes #1896
parent 4c8106e3
No related branches found
No related tags found
No related merge requests found
...@@ -404,17 +404,19 @@ MemtxBitset::count(enum iterator_type type, const char *key, ...@@ -404,17 +404,19 @@ MemtxBitset::count(enum iterator_type type, const char *key,
struct bit_iterator bit_it; struct bit_iterator bit_it;
size_t bit; size_t bit;
if (type == ITER_BITS_ANY_SET) { if (type == ITER_BITS_ANY_SET) {
/* /**
* Optimization: get the number of items for each requested bit * Optimization: for an empty key return 0.
* and then found the maximum.
*/ */
bit_iterator_init(&bit_it, bitset_key, bitset_key_size, true); bit_iterator_init(&bit_it, bitset_key, bitset_key_size, true);
size_t result = 0; bit = bit_iterator_next(&bit_it);
while ((bit = bit_iterator_next(&bit_it)) != SIZE_MAX) { if (bit == SIZE_MAX)
size_t count = bitset_index_count(&m_index, bit); return 0;
result = MAX(result, count); /**
} * Optimiation: for a single bit key use
return result; * bitset_index_count().
*/
if (bit_iterator_next(&bit_it) == SIZE_MAX)
return bitset_index_count(&m_index, bit);
} else if (type == ITER_BITS_ALL_SET) { } else if (type == ITER_BITS_ALL_SET) {
/** /**
* Optimization: for an empty key return the number of items * Optimization: for an empty key return the number of items
......
...@@ -1880,3 +1880,63 @@ space:drop() ...@@ -1880,3 +1880,63 @@ space:drop()
space = nil space = nil
--- ---
... ...
-- https://github.com/tarantool/tarantool/issues/1896 wrong countspace = box.schema.space.create('test')
s = box.schema.space.create('test')
---
...
_ = s:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true })
---
...
i = s:create_index('bitset', { type = 'bitset', parts = {2, 'num'}, unique = false })
---
...
s:insert{1, 0}
---
- [1, 0]
...
s:insert{2, 0}
---
- [2, 0]
...
s:insert{3, 0}
---
- [3, 0]
...
s:insert{4, 2}
---
- [4, 2]
...
s:insert{5, 2}
---
- [5, 2]
...
s:insert{6, 3}
---
- [6, 3]
...
s:insert{7, 4}
---
- [7, 4]
...
s:insert{8, 5}
---
- [8, 5]
...
s:insert{9, 8}
---
- [9, 8]
...
#i:select(7, {iterator = box.index.BITS_ANY_SET})
---
- 5
...
i:count(7, {iterator = box.index.BITS_ANY_SET})
---
- 5
...
s:drop()
---
...
s = nil
---
...
...@@ -115,3 +115,20 @@ _ = space:create_index('bitset', { type = 'bitset', parts = {2, 'number'}, uniqu ...@@ -115,3 +115,20 @@ _ = space:create_index('bitset', { type = 'bitset', parts = {2, 'number'}, uniqu
space:drop() space:drop()
space = nil space = nil
-- https://github.com/tarantool/tarantool/issues/1896 wrong countspace = box.schema.space.create('test')
s = box.schema.space.create('test')
_ = s:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true })
i = s:create_index('bitset', { type = 'bitset', parts = {2, 'num'}, unique = false })
s:insert{1, 0}
s:insert{2, 0}
s:insert{3, 0}
s:insert{4, 2}
s:insert{5, 2}
s:insert{6, 3}
s:insert{7, 4}
s:insert{8, 5}
s:insert{9, 8}
#i:select(7, {iterator = box.index.BITS_ANY_SET})
i:count(7, {iterator = box.index.BITS_ANY_SET})
s:drop()
s = nil
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment