diff --git a/src/box/memtx_bitset.cc b/src/box/memtx_bitset.cc index 56ad38dc2b4d9ec191355fb16ba97b7f742a428e..89e7cbe01ee455f783d9e6dc6a42a8683bad08eb 100644 --- a/src/box/memtx_bitset.cc +++ b/src/box/memtx_bitset.cc @@ -404,17 +404,19 @@ MemtxBitset::count(enum iterator_type type, const char *key, struct bit_iterator bit_it; size_t bit; if (type == ITER_BITS_ANY_SET) { - /* - * Optimization: get the number of items for each requested bit - * and then found the maximum. + /** + * Optimization: for an empty key return 0. */ bit_iterator_init(&bit_it, bitset_key, bitset_key_size, true); - size_t result = 0; - while ((bit = bit_iterator_next(&bit_it)) != SIZE_MAX) { - size_t count = bitset_index_count(&m_index, bit); - result = MAX(result, count); - } - return result; + bit = bit_iterator_next(&bit_it); + if (bit == SIZE_MAX) + return 0; + /** + * Optimiation: for a single bit key use + * 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) { /** * Optimization: for an empty key return the number of items diff --git a/test/box/bitset.result b/test/box/bitset.result index 9ec900510dda8a49bd74e8618677a8c1702fad36..444190314bc94c2f104c17855a4e38b73eee83ac 100644 --- a/test/box/bitset.result +++ b/test/box/bitset.result @@ -1880,3 +1880,63 @@ space:drop() 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 +--- +... diff --git a/test/box/bitset.test.lua b/test/box/bitset.test.lua index 2fc80a889616e0a622c78a59076fc61fefa32d5a..656f311c927b7083a9133f23c69d76518cb748c8 100644 --- a/test/box/bitset.test.lua +++ b/test/box/bitset.test.lua @@ -115,3 +115,20 @@ _ = space:create_index('bitset', { type = 'bitset', parts = {2, 'number'}, uniqu space:drop() 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