Fix intersection on empty posting lists.

This commit is contained in:
Kishore Nallan 2021-06-19 16:52:27 +05:30
parent 3428a740b6
commit 315d4d0aed
2 changed files with 61 additions and 0 deletions

View File

@ -613,6 +613,20 @@ void posting_list_t::merge(const std::vector<posting_list_t*>& posting_lists, st
// Inspired by: https://stackoverflow.com/a/25509185/131050
void posting_list_t::intersect(const std::vector<posting_list_t*>& posting_lists, std::vector<uint32_t>& result_ids) {
if(posting_lists.empty()) {
return;
}
if(posting_lists.size() == 1) {
auto it = posting_lists[0]->new_iterator();
while(it.valid()) {
result_ids.push_back(it.id());
it.next();
}
return ;
}
auto its = std::vector<posting_list_t::iterator_t>();
its.reserve(posting_lists.size());
@ -650,6 +664,11 @@ void posting_list_t::intersect(const std::vector<posting_list_t*>& posting_lists
bool posting_list_t::block_intersect(const std::vector<posting_list_t*>& posting_lists, const size_t batch_size,
std::vector<posting_list_t::iterator_t>& its,
result_iter_state_t& iter_state) {
if(posting_lists.empty()) {
return false;
}
if(its.empty()) {
its.reserve(posting_lists.size());
@ -666,6 +685,16 @@ bool posting_list_t::block_intersect(const std::vector<posting_list_t*>& posting
size_t num_lists = its.size();
switch (num_lists) {
case 1:
while(its[0].valid()) {
iter_state.ids.push_back(its[0].id());
its[0].next();
if(iter_state.ids.size() == batch_size) {
return its[0].valid();
}
}
break;
case 2:
while(!at_end2(its)) {
if(equals2(its)) {

View File

@ -633,6 +633,38 @@ TEST(PostingListTest, IntersectionBasics) {
ASSERT_FALSE(has_more);
ASSERT_EQ(1, iter_state2.ids.size());
ASSERT_EQ(20, iter_state2.ids[0]);
// single item itersection
std::vector<posting_list_t*> single_item_list = {&p1};
result_ids.clear();
posting_list_t::intersect(single_item_list, result_ids);
std::vector<uint32_t> expected_ids = {0, 2, 3, 20};
ASSERT_EQ(expected_ids.size(), result_ids.size());
for(size_t i = 0; i < expected_ids.size(); i++) {
ASSERT_EQ(expected_ids[i], result_ids[i]);
}
std::vector<posting_list_t::iterator_t> its3;
posting_list_t::result_iter_state_t iter_state3;
has_more = posting_list_t::block_intersect(single_item_list, 2, its3, iter_state3);
ASSERT_TRUE(has_more);
ASSERT_EQ(2, iter_state3.ids.size());
has_more = posting_list_t::block_intersect(single_item_list, 2, its3, iter_state3);
ASSERT_FALSE(has_more);
ASSERT_EQ(2, iter_state3.ids.size());
// empty intersection list
std::vector<posting_list_t*> empty_list;
result_ids.clear();
posting_list_t::intersect(empty_list, result_ids);
ASSERT_EQ(0, result_ids.size());
std::vector<posting_list_t::iterator_t> its4;
posting_list_t::result_iter_state_t iter_state4;
has_more = posting_list_t::block_intersect(empty_list, 1, its4, iter_state4);
ASSERT_FALSE(has_more);
ASSERT_EQ(0, iter_state4.ids.size());
}
TEST(PostingListTest, ResultsAndOffsetsBasics) {