mirror of
https://github.com/typesense/typesense.git
synced 2025-05-17 12:12:35 +08:00
Fix intersection on empty posting lists.
This commit is contained in:
parent
3428a740b6
commit
315d4d0aed
@ -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)) {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user