mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 17:18:35 +08:00
enhance: remove timestamp_filter after retrieve (#35207)
#35226 Signed-off-by: luzhang <luzhang@zilliz.com> Co-authored-by: luzhang <luzhang@zilliz.com>
This commit is contained in:
parent
241c71fdde
commit
16dd53e7cf
@ -139,7 +139,6 @@ PhyTermFilterExpr::CanSkipSegment() {
|
|||||||
if (segment_->type() == SegmentType::Sealed &&
|
if (segment_->type() == SegmentType::Sealed &&
|
||||||
skip_index.CanSkipBinaryRange<T>(field_id_, 0, min, max, true, true)) {
|
skip_index.CanSkipBinaryRange<T>(field_id_, 0, min, max, true, true)) {
|
||||||
cached_bits_.resize(active_count_, false);
|
cached_bits_.resize(active_count_, false);
|
||||||
cached_offsets_ = std::make_shared<ColumnVector>(DataType::INT64, 0);
|
|
||||||
cached_offsets_inited_ = true;
|
cached_offsets_inited_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -178,14 +177,9 @@ PhyTermFilterExpr::InitPkCacheOffset() {
|
|||||||
auto [uids, seg_offsets] =
|
auto [uids, seg_offsets] =
|
||||||
segment_->search_ids(*id_array, query_timestamp_);
|
segment_->search_ids(*id_array, query_timestamp_);
|
||||||
cached_bits_.resize(active_count_, false);
|
cached_bits_.resize(active_count_, false);
|
||||||
cached_offsets_ =
|
|
||||||
std::make_shared<ColumnVector>(DataType::INT64, seg_offsets.size());
|
|
||||||
int64_t* cached_offsets_ptr = (int64_t*)cached_offsets_->GetRawData();
|
|
||||||
int i = 0;
|
|
||||||
for (const auto& offset : seg_offsets) {
|
for (const auto& offset : seg_offsets) {
|
||||||
auto _offset = (int64_t)offset.get();
|
auto _offset = (int64_t)offset.get();
|
||||||
cached_bits_[_offset] = true;
|
cached_bits_[_offset] = true;
|
||||||
cached_offsets_ptr[i++] = _offset;
|
|
||||||
}
|
}
|
||||||
cached_offsets_inited_ = true;
|
cached_offsets_inited_ = true;
|
||||||
}
|
}
|
||||||
@ -214,7 +208,10 @@ PhyTermFilterExpr::ExecPkTermImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (use_cache_offsets_) {
|
if (use_cache_offsets_) {
|
||||||
std::vector<VectorPtr> vecs{res_vec, cached_offsets_};
|
auto cache_bits_copy = cached_bits_.clone();
|
||||||
|
std::vector<VectorPtr> vecs{
|
||||||
|
res_vec,
|
||||||
|
std::make_shared<ColumnVector>(std::move(cache_bits_copy))};
|
||||||
return std::make_shared<RowVector>(vecs);
|
return std::make_shared<RowVector>(vecs);
|
||||||
} else {
|
} else {
|
||||||
return res_vec;
|
return res_vec;
|
||||||
|
|||||||
@ -78,21 +78,6 @@ class ExecPlanNodeVisitor : public PlanNodeVisitor {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SetExprCacheOffsets(std::vector<int64_t>&& offsets) {
|
|
||||||
expr_cached_pk_id_offsets_ = std::move(offsets);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AddExprCacheOffset(int64_t offset) {
|
|
||||||
expr_cached_pk_id_offsets_.push_back(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<int64_t>&
|
|
||||||
GetExprCacheOffsets() {
|
|
||||||
return expr_cached_pk_id_offsets_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SetExprUsePkIndex(bool use_pk_index) {
|
SetExprUsePkIndex(bool use_pk_index) {
|
||||||
expr_use_pk_index_ = use_pk_index;
|
expr_use_pk_index_ = use_pk_index;
|
||||||
@ -103,29 +88,11 @@ class ExecPlanNodeVisitor : public PlanNodeVisitor {
|
|||||||
return expr_use_pk_index_;
|
return expr_use_pk_index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ExecuteExprNodeInternal(
|
|
||||||
const std::shared_ptr<milvus::plan::PlanNode>& plannode,
|
|
||||||
const milvus::segcore::SegmentInternalInterface* segment,
|
|
||||||
int64_t active_count,
|
|
||||||
BitsetType& result,
|
|
||||||
bool& cache_offset_getted,
|
|
||||||
std::vector<int64_t>& cache_offset);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExecuteExprNode(const std::shared_ptr<milvus::plan::PlanNode>& plannode,
|
ExecuteExprNode(const std::shared_ptr<milvus::plan::PlanNode>& plannode,
|
||||||
const milvus::segcore::SegmentInternalInterface* segment,
|
const milvus::segcore::SegmentInternalInterface* segment,
|
||||||
int64_t active_count,
|
int64_t active_count,
|
||||||
BitsetType& result) {
|
BitsetType& result);
|
||||||
bool get_cache_offset;
|
|
||||||
std::vector<int64_t> cache_offsets;
|
|
||||||
ExecuteExprNodeInternal(plannode,
|
|
||||||
segment,
|
|
||||||
active_count,
|
|
||||||
result,
|
|
||||||
get_cache_offset,
|
|
||||||
cache_offsets);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename VectorType>
|
template <typename VectorType>
|
||||||
@ -140,6 +107,5 @@ class ExecPlanNodeVisitor : public PlanNodeVisitor {
|
|||||||
SearchResultOpt search_result_opt_;
|
SearchResultOpt search_result_opt_;
|
||||||
RetrieveResultOpt retrieve_result_opt_;
|
RetrieveResultOpt retrieve_result_opt_;
|
||||||
bool expr_use_pk_index_ = false;
|
bool expr_use_pk_index_ = false;
|
||||||
std::vector<int64_t> expr_cached_pk_id_offsets_;
|
|
||||||
};
|
};
|
||||||
} // namespace milvus::query
|
} // namespace milvus::query
|
||||||
|
|||||||
@ -2547,7 +2547,6 @@ ExecExprVisitor::ExecTermVisitorImpl(TermExpr& expr_raw) -> BitsetType {
|
|||||||
// If enable plan_visitor pk index cache, pass offsets_ to it
|
// If enable plan_visitor pk index cache, pass offsets_ to it
|
||||||
if (plan_visitor_ != nullptr) {
|
if (plan_visitor_ != nullptr) {
|
||||||
plan_visitor_->SetExprUsePkIndex(true);
|
plan_visitor_->SetExprUsePkIndex(true);
|
||||||
plan_visitor_->SetExprCacheOffsets(std::move(cached_offsets));
|
|
||||||
}
|
}
|
||||||
AssertInfo(bitset.size() == row_count_,
|
AssertInfo(bitset.size() == row_count_,
|
||||||
"[ExecExprVisitor]Size of results not equal row count");
|
"[ExecExprVisitor]Size of results not equal row count");
|
||||||
|
|||||||
@ -75,13 +75,11 @@ empty_search_result(int64_t num_queries, SearchInfo& search_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExecPlanNodeVisitor::ExecuteExprNodeInternal(
|
ExecPlanNodeVisitor::ExecuteExprNode(
|
||||||
const std::shared_ptr<milvus::plan::PlanNode>& plannode,
|
const std::shared_ptr<milvus::plan::PlanNode>& plannode,
|
||||||
const milvus::segcore::SegmentInternalInterface* segment,
|
const milvus::segcore::SegmentInternalInterface* segment,
|
||||||
int64_t active_count,
|
int64_t active_count,
|
||||||
BitsetType& bitset_holder,
|
BitsetType& bitset_holder) {
|
||||||
bool& cache_offset_getted,
|
|
||||||
std::vector<int64_t>& cache_offset) {
|
|
||||||
bitset_holder.clear();
|
bitset_holder.clear();
|
||||||
LOG_DEBUG("plannode: {}, active_count: {}, timestamp: {}",
|
LOG_DEBUG("plannode: {}, active_count: {}, timestamp: {}",
|
||||||
plannode->ToString(),
|
plannode->ToString(),
|
||||||
@ -94,6 +92,7 @@ ExecPlanNodeVisitor::ExecuteExprNodeInternal(
|
|||||||
|
|
||||||
auto task =
|
auto task =
|
||||||
milvus::exec::Task::Create(DEFAULT_TASK_ID, plan, 0, query_context);
|
milvus::exec::Task::Create(DEFAULT_TASK_ID, plan, 0, query_context);
|
||||||
|
bool cache_offset_getted = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto result = task->Next();
|
auto result = task->Next();
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -115,20 +114,17 @@ ExecPlanNodeVisitor::ExecuteExprNodeInternal(
|
|||||||
|
|
||||||
if (!cache_offset_getted) {
|
if (!cache_offset_getted) {
|
||||||
// offset cache only get once because not support iterator batch
|
// offset cache only get once because not support iterator batch
|
||||||
auto cache_offset_vec =
|
auto cache_bits_vec =
|
||||||
std::dynamic_pointer_cast<ColumnVector>(row->child(1));
|
std::dynamic_pointer_cast<ColumnVector>(row->child(1));
|
||||||
// If get empty cached offsets. mean no record hits in this segment
|
TargetBitmapView view(cache_bits_vec->GetRawData(),
|
||||||
|
cache_bits_vec->size());
|
||||||
|
// If get empty cached bits. mean no record hits in this segment
|
||||||
// no need to get next batch.
|
// no need to get next batch.
|
||||||
if (cache_offset_vec->size() == 0) {
|
if (view.count() == 0) {
|
||||||
bitset_holder.resize(active_count);
|
bitset_holder.resize(active_count);
|
||||||
task->RequestCancel();
|
task->RequestCancel();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto cache_offset_vec_ptr =
|
|
||||||
(int64_t*)(cache_offset_vec->GetRawData());
|
|
||||||
for (size_t i = 0; i < cache_offset_vec->size(); ++i) {
|
|
||||||
cache_offset.push_back(cache_offset_vec_ptr[i]);
|
|
||||||
}
|
|
||||||
cache_offset_getted = true;
|
cache_offset_getted = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -281,17 +277,12 @@ ExecPlanNodeVisitor::visit(RetrievePlanNode& node) {
|
|||||||
bitset_holder.resize(active_count);
|
bitset_holder.resize(active_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This flag used to indicate whether to get offset from expr module that
|
|
||||||
// speeds up mvcc filter in the next interface: "timestamp_filter"
|
|
||||||
bool get_cache_offset = false;
|
|
||||||
std::vector<int64_t> cache_offsets;
|
std::vector<int64_t> cache_offsets;
|
||||||
if (node.filter_plannode_.has_value()) {
|
if (node.filter_plannode_.has_value()) {
|
||||||
ExecuteExprNodeInternal(node.filter_plannode_.value(),
|
ExecuteExprNode(node.filter_plannode_.value(),
|
||||||
segment,
|
segment,
|
||||||
active_count,
|
active_count,
|
||||||
bitset_holder,
|
bitset_holder);
|
||||||
get_cache_offset,
|
|
||||||
cache_offsets);
|
|
||||||
bitset_holder.flip();
|
bitset_holder.flip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,16 +304,7 @@ ExecPlanNodeVisitor::visit(RetrievePlanNode& node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
retrieve_result.total_data_cnt_ = bitset_holder.size();
|
retrieve_result.total_data_cnt_ = bitset_holder.size();
|
||||||
bool false_filtered_out = false;
|
auto results_pair = segment->find_first(node.limit_, bitset_holder);
|
||||||
if (get_cache_offset) {
|
|
||||||
segment->timestamp_filter(bitset_holder, cache_offsets, timestamp_);
|
|
||||||
} else {
|
|
||||||
bitset_holder.flip();
|
|
||||||
false_filtered_out = true;
|
|
||||||
segment->timestamp_filter(bitset_holder, timestamp_);
|
|
||||||
}
|
|
||||||
auto results_pair =
|
|
||||||
segment->find_first(node.limit_, bitset_holder, false_filtered_out);
|
|
||||||
retrieve_result.result_offsets_ = std::move(results_pair.first);
|
retrieve_result.result_offsets_ = std::move(results_pair.first);
|
||||||
retrieve_result.has_more_result = results_pair.second;
|
retrieve_result.has_more_result = results_pair.second;
|
||||||
retrieve_result_opt_ = std::move(retrieve_result);
|
retrieve_result_opt_ = std::move(retrieve_result);
|
||||||
|
|||||||
@ -63,9 +63,7 @@ class OffsetMap {
|
|||||||
using OffsetType = int64_t;
|
using OffsetType = int64_t;
|
||||||
// TODO: in fact, we can retrieve the pk here. Not sure which way is more efficient.
|
// TODO: in fact, we can retrieve the pk here. Not sure which way is more efficient.
|
||||||
virtual std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
virtual std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const = 0;
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const = 0;
|
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
clear() = 0;
|
clear() = 0;
|
||||||
@ -169,9 +167,7 @@ class OffsetOrderedMap : public OffsetMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const override {
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const override {
|
|
||||||
std::shared_lock<std::shared_mutex> lck(mtx_);
|
std::shared_lock<std::shared_mutex> lck(mtx_);
|
||||||
|
|
||||||
if (limit == Unlimited || limit == NoLimit) {
|
if (limit == Unlimited || limit == NoLimit) {
|
||||||
@ -180,7 +176,7 @@ class OffsetOrderedMap : public OffsetMap {
|
|||||||
|
|
||||||
// TODO: we can't retrieve pk by offset very conveniently.
|
// TODO: we can't retrieve pk by offset very conveniently.
|
||||||
// Selectivity should be done outside.
|
// Selectivity should be done outside.
|
||||||
return find_first_by_index(limit, bitset, false_filtered_out);
|
return find_first_by_index(limit, bitset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -191,15 +187,10 @@ class OffsetOrderedMap : public OffsetMap {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first_by_index(int64_t limit,
|
find_first_by_index(int64_t limit, const BitsetType& bitset) const {
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const {
|
|
||||||
int64_t hit_num = 0; // avoid counting the number everytime.
|
int64_t hit_num = 0; // avoid counting the number everytime.
|
||||||
int64_t cnt = bitset.count();
|
|
||||||
auto size = bitset.size();
|
auto size = bitset.size();
|
||||||
if (!false_filtered_out) {
|
int64_t cnt = size - bitset.count();
|
||||||
cnt = size - bitset.count();
|
|
||||||
}
|
|
||||||
limit = std::min(limit, cnt);
|
limit = std::min(limit, cnt);
|
||||||
std::vector<int64_t> seg_offsets;
|
std::vector<int64_t> seg_offsets;
|
||||||
seg_offsets.reserve(limit);
|
seg_offsets.reserve(limit);
|
||||||
@ -214,7 +205,7 @@ class OffsetOrderedMap : public OffsetMap {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bitset[seg_offset] ^ false_filtered_out)) {
|
if (!bitset[seg_offset]) {
|
||||||
seg_offsets.push_back(seg_offset);
|
seg_offsets.push_back(seg_offset);
|
||||||
hit_num++;
|
hit_num++;
|
||||||
// PK hit, no need to continue traversing offsets with the same PK.
|
// PK hit, no need to continue traversing offsets with the same PK.
|
||||||
@ -346,9 +337,7 @@ class OffsetOrderedArray : public OffsetMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const override {
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const override {
|
|
||||||
check_search();
|
check_search();
|
||||||
|
|
||||||
if (limit == Unlimited || limit == NoLimit) {
|
if (limit == Unlimited || limit == NoLimit) {
|
||||||
@ -357,7 +346,7 @@ class OffsetOrderedArray : public OffsetMap {
|
|||||||
|
|
||||||
// TODO: we can't retrieve pk by offset very conveniently.
|
// TODO: we can't retrieve pk by offset very conveniently.
|
||||||
// Selectivity should be done outside.
|
// Selectivity should be done outside.
|
||||||
return find_first_by_index(limit, bitset, false_filtered_out);
|
return find_first_by_index(limit, bitset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -368,15 +357,10 @@ class OffsetOrderedArray : public OffsetMap {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first_by_index(int64_t limit,
|
find_first_by_index(int64_t limit, const BitsetType& bitset) const {
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const {
|
|
||||||
int64_t hit_num = 0; // avoid counting the number everytime.
|
int64_t hit_num = 0; // avoid counting the number everytime.
|
||||||
int64_t cnt = bitset.count();
|
|
||||||
auto size = bitset.size();
|
auto size = bitset.size();
|
||||||
if (!false_filtered_out) {
|
int64_t cnt = size - bitset.count();
|
||||||
cnt = size - bitset.count();
|
|
||||||
}
|
|
||||||
auto more_hit_than_limit = cnt > limit;
|
auto more_hit_than_limit = cnt > limit;
|
||||||
limit = std::min(limit, cnt);
|
limit = std::min(limit, cnt);
|
||||||
std::vector<int64_t> seg_offsets;
|
std::vector<int64_t> seg_offsets;
|
||||||
@ -389,7 +373,7 @@ class OffsetOrderedArray : public OffsetMap {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bitset[seg_offset] ^ false_filtered_out)) {
|
if (!bitset[seg_offset]) {
|
||||||
seg_offsets.push_back(seg_offset);
|
seg_offsets.push_back(seg_offset);
|
||||||
hit_num++;
|
hit_num++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -307,11 +307,8 @@ class SegmentGrowingImpl : public SegmentGrowing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const override {
|
||||||
const BitsetType& bitset,
|
return insert_record_.pk2offset_->find_first(limit, bitset);
|
||||||
bool false_filtered_out) const override {
|
|
||||||
return insert_record_.pk2offset_->find_first(
|
|
||||||
limit, bitset, false_filtered_out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
@ -340,9 +340,7 @@ class SegmentInternalInterface : public SegmentInterface {
|
|||||||
* @return All candidates offsets.
|
* @return All candidates offsets.
|
||||||
*/
|
*/
|
||||||
virtual std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
virtual std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const = 0;
|
||||||
const BitsetType& bitset,
|
|
||||||
bool false_filtered_out) const = 0;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FillTargetEntry(
|
FillTargetEntry(
|
||||||
|
|||||||
@ -151,11 +151,8 @@ class SegmentSealedImpl : public SegmentSealed {
|
|||||||
const Timestamp* timestamps) override;
|
const Timestamp* timestamps) override;
|
||||||
|
|
||||||
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
std::pair<std::vector<OffsetMap::OffsetType>, bool>
|
||||||
find_first(int64_t limit,
|
find_first(int64_t limit, const BitsetType& bitset) const override {
|
||||||
const BitsetType& bitset,
|
return insert_record_.pk2offset_->find_first(limit, bitset);
|
||||||
bool false_filtered_out) const override {
|
|
||||||
return insert_record_.pk2offset_->find_first(
|
|
||||||
limit, bitset, false_filtered_out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate: output[i] = Vec[seg_offset[i]]
|
// Calculate: output[i] = Vec[seg_offset[i]]
|
||||||
|
|||||||
@ -66,7 +66,7 @@ TYPED_TEST_SUITE_P(TypedOffsetOrderedArrayTest);
|
|||||||
|
|
||||||
TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
||||||
// not sealed.
|
// not sealed.
|
||||||
ASSERT_ANY_THROW(this->map_.find_first(Unlimited, {}, true));
|
ASSERT_ANY_THROW(this->map_.find_first(Unlimited, {}));
|
||||||
|
|
||||||
// insert 10 entities.
|
// insert 10 entities.
|
||||||
int num = 10;
|
int num = 10;
|
||||||
@ -81,10 +81,8 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
|||||||
// all is satisfied.
|
// all is satisfied.
|
||||||
{
|
{
|
||||||
BitsetType all(num);
|
BitsetType all(num);
|
||||||
all.set();
|
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(num / 2, all);
|
||||||
this->map_.find_first(num / 2, all, true);
|
|
||||||
ASSERT_EQ(num / 2, offsets.size());
|
ASSERT_EQ(num / 2, offsets.size());
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -93,7 +91,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] =
|
||||||
this->map_.find_first(Unlimited, all, true);
|
this->map_.find_first(Unlimited, all);
|
||||||
ASSERT_EQ(num, offsets.size());
|
ASSERT_EQ(num, offsets.size());
|
||||||
ASSERT_FALSE(has_more_res);
|
ASSERT_FALSE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -104,10 +102,9 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
|||||||
{
|
{
|
||||||
// corner case, segment offset exceeds the size of bitset.
|
// corner case, segment offset exceeds the size of bitset.
|
||||||
BitsetType all_minus_1(num - 1);
|
BitsetType all_minus_1(num - 1);
|
||||||
all_minus_1.set();
|
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] =
|
||||||
this->map_.find_first(num / 2, all_minus_1, true);
|
this->map_.find_first(num / 2, all_minus_1);
|
||||||
ASSERT_EQ(num / 2, offsets.size());
|
ASSERT_EQ(num / 2, offsets.size());
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -116,7 +113,7 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] =
|
||||||
this->map_.find_first(Unlimited, all_minus_1, true);
|
this->map_.find_first(Unlimited, all_minus_1);
|
||||||
ASSERT_EQ(all_minus_1.size(), offsets.size());
|
ASSERT_EQ(all_minus_1.size(), offsets.size());
|
||||||
ASSERT_FALSE(has_more_res);
|
ASSERT_FALSE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -127,11 +124,11 @@ TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) {
|
|||||||
{
|
{
|
||||||
// none is satisfied.
|
// none is satisfied.
|
||||||
BitsetType none(num);
|
BitsetType none(num);
|
||||||
none.reset();
|
none.set();
|
||||||
auto result_pair = this->map_.find_first(num / 2, none, true);
|
auto result_pair = this->map_.find_first(num / 2, none);
|
||||||
ASSERT_EQ(0, result_pair.first.size());
|
ASSERT_EQ(0, result_pair.first.size());
|
||||||
ASSERT_FALSE(result_pair.second);
|
ASSERT_FALSE(result_pair.second);
|
||||||
result_pair = this->map_.find_first(NoLimit, none, true);
|
result_pair = this->map_.find_first(NoLimit, none);
|
||||||
ASSERT_EQ(0, result_pair.first.size());
|
ASSERT_EQ(0, result_pair.first.size());
|
||||||
ASSERT_FALSE(result_pair.second);
|
ASSERT_FALSE(result_pair.second);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,8 +62,7 @@ TYPED_TEST_SUITE_P(TypedOffsetOrderedMapTest);
|
|||||||
TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
||||||
// no data.
|
// no data.
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(Unlimited, {});
|
||||||
this->map_.find_first(Unlimited, {}, true);
|
|
||||||
ASSERT_EQ(0, offsets.size());
|
ASSERT_EQ(0, offsets.size());
|
||||||
ASSERT_FALSE(has_more_res);
|
ASSERT_FALSE(has_more_res);
|
||||||
}
|
}
|
||||||
@ -76,11 +75,10 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
|||||||
|
|
||||||
// all is satisfied.
|
// all is satisfied.
|
||||||
BitsetType all(num);
|
BitsetType all(num);
|
||||||
all.set();
|
all.reset();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(num / 2, all);
|
||||||
this->map_.find_first(num / 2, all, true);
|
|
||||||
ASSERT_EQ(num / 2, offsets.size());
|
ASSERT_EQ(num / 2, offsets.size());
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -88,8 +86,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(Unlimited, all);
|
||||||
this->map_.find_first(Unlimited, all, true);
|
|
||||||
ASSERT_EQ(num, offsets.size());
|
ASSERT_EQ(num, offsets.size());
|
||||||
ASSERT_FALSE(has_more_res);
|
ASSERT_FALSE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -99,10 +96,10 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
|||||||
|
|
||||||
// corner case, segment offset exceeds the size of bitset.
|
// corner case, segment offset exceeds the size of bitset.
|
||||||
BitsetType all_minus_1(num - 1);
|
BitsetType all_minus_1(num - 1);
|
||||||
all_minus_1.set();
|
all_minus_1.reset();
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] =
|
||||||
this->map_.find_first(num / 2, all_minus_1, true);
|
this->map_.find_first(num / 2, all_minus_1);
|
||||||
ASSERT_EQ(num / 2, offsets.size());
|
ASSERT_EQ(num / 2, offsets.size());
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -111,7 +108,7 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] =
|
||||||
this->map_.find_first(Unlimited, all_minus_1, true);
|
this->map_.find_first(Unlimited, all_minus_1);
|
||||||
ASSERT_EQ(all_minus_1.size(), offsets.size());
|
ASSERT_EQ(all_minus_1.size(), offsets.size());
|
||||||
ASSERT_FALSE(has_more_res);
|
ASSERT_FALSE(has_more_res);
|
||||||
for (int i = 1; i < offsets.size(); i++) {
|
for (int i = 1; i < offsets.size(); i++) {
|
||||||
@ -121,16 +118,14 @@ TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) {
|
|||||||
|
|
||||||
// none is satisfied.
|
// none is satisfied.
|
||||||
BitsetType none(num);
|
BitsetType none(num);
|
||||||
none.reset();
|
none.set();
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(num / 2, none);
|
||||||
this->map_.find_first(num / 2, none, true);
|
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
ASSERT_EQ(0, offsets.size());
|
ASSERT_EQ(0, offsets.size());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto [offsets, has_more_res] =
|
auto [offsets, has_more_res] = this->map_.find_first(NoLimit, none);
|
||||||
this->map_.find_first(NoLimit, none, true);
|
|
||||||
ASSERT_TRUE(has_more_res);
|
ASSERT_TRUE(has_more_res);
|
||||||
ASSERT_EQ(0, offsets.size());
|
ASSERT_EQ(0, offsets.size());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user