From 034e0c138612440aa8cd4a5014fa5e25bb8cf13b Mon Sep 17 00:00:00 2001 From: longjiquan Date: Tue, 25 Jul 2023 16:02:28 +0800 Subject: [PATCH] Push down the limit operator to segcore Signed-off-by: longjiquan --- internal/core/CMakeLists.txt | 6 +- internal/core/src/pb/plan.pb.cc | 69 ++++-- internal/core/src/pb/plan.pb.h | 31 +++ internal/core/src/query/PlanNode.h | 3 +- internal/core/src/query/PlanProto.cpp | 5 +- .../query/visitors/ExecPlanNodeVisitor.cpp | 28 +-- internal/core/src/segcore/InsertRecord.h | 98 ++++++++- .../core/src/segcore/SegmentGrowingImpl.cpp | 49 ----- .../core/src/segcore/SegmentGrowingImpl.h | 21 +- .../core/src/segcore/SegmentInterface.cpp | 35 ++- internal/core/src/segcore/SegmentInterface.h | 23 +- .../core/src/segcore/SegmentSealedImpl.cpp | 45 ---- internal/core/src/segcore/SegmentSealedImpl.h | 21 +- internal/core/unittest/CMakeLists.txt | 2 + .../unittest/test_offset_ordered_array.cpp | 107 +++++++++ .../core/unittest/test_offset_ordered_map.cpp | 100 +++++++++ internal/proto/plan.proto | 1 + internal/proto/planpb/plan.pb.go | 205 +++++++++--------- internal/proxy/task_query.go | 1 + internal/querynodev2/segments/segment.go | 4 +- 20 files changed, 581 insertions(+), 273 deletions(-) create mode 100644 internal/core/unittest/test_offset_ordered_array.cpp create mode 100644 internal/core/unittest/test_offset_ordered_map.cpp diff --git a/internal/core/CMakeLists.txt b/internal/core/CMakeLists.txt index c0ee2c4e564c5..2b49e3448834b 100644 --- a/internal/core/CMakeLists.txt +++ b/internal/core/CMakeLists.txt @@ -123,8 +123,12 @@ if (LINUX OR MSYS) "-DELPP_THREAD_SAFE" "-fopenmp" "-Werror" - "-O3" ) + if (CMAKE_BUILD_TYPE STREQUAL "Release") + append_flags( CMAKE_CXX_FLAGS + "-O3" + ) + endif() endif () if ( APPLE ) diff --git a/internal/core/src/pb/plan.pb.cc b/internal/core/src/pb/plan.pb.cc index 66340e72656ab..5537fb3ecd4b5 100644 --- a/internal/core/src/pb/plan.pb.cc +++ b/internal/core/src/pb/plan.pb.cc @@ -282,6 +282,7 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORIT PROTOBUF_CONSTEXPR QueryPlanNode::QueryPlanNode( ::_pbi::ConstantInitialized): _impl_{ /*decltype(_impl_.predicates_)*/nullptr + , /*decltype(_impl_.limit_)*/int64_t{0} , /*decltype(_impl_.is_count_)*/false , /*decltype(_impl_._cached_size_)*/{}} {} struct QueryPlanNodeDefaultTypeInternal { @@ -492,6 +493,7 @@ const uint32_t TableStruct_plan_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(pro ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(::milvus::proto::plan::QueryPlanNode, _impl_.predicates_), PROTOBUF_FIELD_OFFSET(::milvus::proto::plan::QueryPlanNode, _impl_.is_count_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::plan::QueryPlanNode, _impl_.limit_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::milvus::proto::plan::PlanNode, _internal_metadata_), ~0u, // no _extensions_ @@ -523,7 +525,7 @@ static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protode { 138, -1, -1, sizeof(::milvus::proto::plan::Expr)}, { 156, -1, -1, sizeof(::milvus::proto::plan::VectorANNS)}, { 167, -1, -1, sizeof(::milvus::proto::plan::QueryPlanNode)}, - { 175, -1, -1, sizeof(::milvus::proto::plan::PlanNode)}, + { 176, -1, -1, sizeof(::milvus::proto::plan::PlanNode)}, }; static const ::_pb::Message* const file_default_instances[] = { @@ -625,29 +627,30 @@ const char descriptor_table_protodef_plan_2eproto[] PROTOBUF_SECTION_VARIABLE(pr "inary\030\001 \001(\010\022\020\n\010field_id\030\002 \001(\003\022+\n\npredica" "tes\030\003 \001(\0132\027.milvus.proto.plan.Expr\0220\n\nqu" "ery_info\030\004 \001(\0132\034.milvus.proto.plan.Query" - "Info\022\027\n\017placeholder_tag\030\005 \001(\t\"N\n\rQueryPl" + "Info\022\027\n\017placeholder_tag\030\005 \001(\t\"]\n\rQueryPl" "anNode\022+\n\npredicates\030\001 \001(\0132\027.milvus.prot" - "o.plan.Expr\022\020\n\010is_count\030\002 \001(\010\"\304\001\n\010PlanNo" - "de\0224\n\013vector_anns\030\001 \001(\0132\035.milvus.proto.p" - "lan.VectorANNSH\000\022-\n\npredicates\030\002 \001(\0132\027.m" - "ilvus.proto.plan.ExprH\000\0221\n\005query\030\004 \001(\0132 " - ".milvus.proto.plan.QueryPlanNodeH\000\022\030\n\020ou" - "tput_field_ids\030\003 \003(\003B\006\n\004node*\272\001\n\006OpType\022" - "\013\n\007Invalid\020\000\022\017\n\013GreaterThan\020\001\022\020\n\014Greater" - "Equal\020\002\022\014\n\010LessThan\020\003\022\r\n\tLessEqual\020\004\022\t\n\005" - "Equal\020\005\022\014\n\010NotEqual\020\006\022\017\n\013PrefixMatch\020\007\022\020" - "\n\014PostfixMatch\020\010\022\t\n\005Match\020\t\022\t\n\005Range\020\n\022\006" - "\n\002In\020\013\022\t\n\005NotIn\020\014*G\n\013ArithOpType\022\013\n\007Unkn" - "own\020\000\022\007\n\003Add\020\001\022\007\n\003Sub\020\002\022\007\n\003Mul\020\003\022\007\n\003Div\020" - "\004\022\007\n\003Mod\020\005B3Z1github.com/milvus-io/milvu" - "s/internal/proto/planpbb\006proto3" + "o.plan.Expr\022\020\n\010is_count\030\002 \001(\010\022\r\n\005limit\030\003" + " \001(\003\"\304\001\n\010PlanNode\0224\n\013vector_anns\030\001 \001(\0132\035" + ".milvus.proto.plan.VectorANNSH\000\022-\n\npredi" + "cates\030\002 \001(\0132\027.milvus.proto.plan.ExprH\000\0221" + "\n\005query\030\004 \001(\0132 .milvus.proto.plan.QueryP" + "lanNodeH\000\022\030\n\020output_field_ids\030\003 \003(\003B\006\n\004n" + "ode*\272\001\n\006OpType\022\013\n\007Invalid\020\000\022\017\n\013GreaterTh" + "an\020\001\022\020\n\014GreaterEqual\020\002\022\014\n\010LessThan\020\003\022\r\n\t" + "LessEqual\020\004\022\t\n\005Equal\020\005\022\014\n\010NotEqual\020\006\022\017\n\013" + "PrefixMatch\020\007\022\020\n\014PostfixMatch\020\010\022\t\n\005Match" + "\020\t\022\t\n\005Range\020\n\022\006\n\002In\020\013\022\t\n\005NotIn\020\014*G\n\013Arit" + "hOpType\022\013\n\007Unknown\020\000\022\007\n\003Add\020\001\022\007\n\003Sub\020\002\022\007" + "\n\003Mul\020\003\022\007\n\003Div\020\004\022\007\n\003Mod\020\005B3Z1github.com/" + "milvus-io/milvus/internal/proto/planpbb\006" + "proto3" ; static const ::_pbi::DescriptorTable* const descriptor_table_plan_2eproto_deps[1] = { &::descriptor_table_schema_2eproto, }; static ::_pbi::once_flag descriptor_table_plan_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_plan_2eproto = { - false, false, 3671, descriptor_table_protodef_plan_2eproto, + false, false, 3686, descriptor_table_protodef_plan_2eproto, "plan.proto", &descriptor_table_plan_2eproto_once, descriptor_table_plan_2eproto_deps, 1, 19, schemas, file_default_instances, TableStruct_plan_2eproto::offsets, @@ -5982,6 +5985,7 @@ QueryPlanNode::QueryPlanNode(const QueryPlanNode& from) QueryPlanNode* const _this = this; (void)_this; new (&_impl_) Impl_{ decltype(_impl_.predicates_){nullptr} + , decltype(_impl_.limit_){} , decltype(_impl_.is_count_){} , /*decltype(_impl_._cached_size_)*/{}}; @@ -5989,7 +5993,9 @@ QueryPlanNode::QueryPlanNode(const QueryPlanNode& from) if (from._internal_has_predicates()) { _this->_impl_.predicates_ = new ::milvus::proto::plan::Expr(*from._impl_.predicates_); } - _this->_impl_.is_count_ = from._impl_.is_count_; + ::memcpy(&_impl_.limit_, &from._impl_.limit_, + static_cast(reinterpret_cast(&_impl_.is_count_) - + reinterpret_cast(&_impl_.limit_)) + sizeof(_impl_.is_count_)); // @@protoc_insertion_point(copy_constructor:milvus.proto.plan.QueryPlanNode) } @@ -5999,6 +6005,7 @@ inline void QueryPlanNode::SharedCtor( (void)is_message_owned; new (&_impl_) Impl_{ decltype(_impl_.predicates_){nullptr} + , decltype(_impl_.limit_){int64_t{0}} , decltype(_impl_.is_count_){false} , /*decltype(_impl_._cached_size_)*/{} }; @@ -6032,7 +6039,9 @@ void QueryPlanNode::Clear() { delete _impl_.predicates_; } _impl_.predicates_ = nullptr; - _impl_.is_count_ = false; + ::memset(&_impl_.limit_, 0, static_cast( + reinterpret_cast(&_impl_.is_count_) - + reinterpret_cast(&_impl_.limit_)) + sizeof(_impl_.is_count_)); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -6058,6 +6067,14 @@ const char* QueryPlanNode::_InternalParse(const char* ptr, ::_pbi::ParseContext* } else goto handle_unusual; continue; + // int64 limit = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { + _impl_.limit_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; default: goto handle_unusual; } // switch @@ -6100,6 +6117,12 @@ uint8_t* QueryPlanNode::_InternalSerialize( target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_is_count(), target); } + // int64 limit = 3; + if (this->_internal_limit() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(3, this->_internal_limit(), target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); @@ -6123,6 +6146,11 @@ size_t QueryPlanNode::ByteSizeLong() const { *_impl_.predicates_); } + // int64 limit = 3; + if (this->_internal_limit() != 0) { + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_limit()); + } + // bool is_count = 2; if (this->_internal_is_count() != 0) { total_size += 1 + 1; @@ -6150,6 +6178,9 @@ void QueryPlanNode::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const :: _this->_internal_mutable_predicates()->::milvus::proto::plan::Expr::MergeFrom( from._internal_predicates()); } + if (from._internal_limit() != 0) { + _this->_internal_set_limit(from._internal_limit()); + } if (from._internal_is_count() != 0) { _this->_internal_set_is_count(from._internal_is_count()); } diff --git a/internal/core/src/pb/plan.pb.h b/internal/core/src/pb/plan.pb.h index d50e473c2e81d..aaae01ba47286 100644 --- a/internal/core/src/pb/plan.pb.h +++ b/internal/core/src/pb/plan.pb.h @@ -3884,6 +3884,7 @@ class QueryPlanNode final : enum : int { kPredicatesFieldNumber = 1, + kLimitFieldNumber = 3, kIsCountFieldNumber = 2, }; // .milvus.proto.plan.Expr predicates = 1; @@ -3904,6 +3905,15 @@ class QueryPlanNode final : ::milvus::proto::plan::Expr* predicates); ::milvus::proto::plan::Expr* unsafe_arena_release_predicates(); + // int64 limit = 3; + void clear_limit(); + int64_t limit() const; + void set_limit(int64_t value); + private: + int64_t _internal_limit() const; + void _internal_set_limit(int64_t value); + public: + // bool is_count = 2; void clear_is_count(); bool is_count() const; @@ -3922,6 +3932,7 @@ class QueryPlanNode final : typedef void DestructorSkippable_; struct Impl_ { ::milvus::proto::plan::Expr* predicates_; + int64_t limit_; bool is_count_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; }; @@ -8118,6 +8129,26 @@ inline void QueryPlanNode::set_is_count(bool value) { // @@protoc_insertion_point(field_set:milvus.proto.plan.QueryPlanNode.is_count) } +// int64 limit = 3; +inline void QueryPlanNode::clear_limit() { + _impl_.limit_ = int64_t{0}; +} +inline int64_t QueryPlanNode::_internal_limit() const { + return _impl_.limit_; +} +inline int64_t QueryPlanNode::limit() const { + // @@protoc_insertion_point(field_get:milvus.proto.plan.QueryPlanNode.limit) + return _internal_limit(); +} +inline void QueryPlanNode::_internal_set_limit(int64_t value) { + + _impl_.limit_ = value; +} +inline void QueryPlanNode::set_limit(int64_t value) { + _internal_set_limit(value); + // @@protoc_insertion_point(field_set:milvus.proto.plan.QueryPlanNode.limit) +} + // ------------------------------------------------------------------- // PlanNode diff --git a/internal/core/src/query/PlanNode.h b/internal/core/src/query/PlanNode.h index 0a85d7535187b..40b62e6e3d7b6 100644 --- a/internal/core/src/query/PlanNode.h +++ b/internal/core/src/query/PlanNode.h @@ -58,7 +58,8 @@ struct RetrievePlanNode : PlanNode { accept(PlanNodeVisitor&) override; std::optional predicate_; - bool is_count; + bool is_count_; + int64_t limit_; }; } // namespace milvus::query diff --git a/internal/core/src/query/PlanProto.cpp b/internal/core/src/query/PlanProto.cpp index 40a18b8b46c37..f339bc8d1318c 100644 --- a/internal/core/src/query/PlanProto.cpp +++ b/internal/core/src/query/PlanProto.cpp @@ -205,7 +205,7 @@ ProtoParser::RetrievePlanNodeFromProto( auto plan_node = [&]() -> std::unique_ptr { auto node = std::make_unique(); if (plan_node_proto.has_predicates()) { // version before 2023.03.30. - node->is_count = false; + node->is_count_ = false; auto& predicate_proto = plan_node_proto.predicates(); auto expr_opt = [&]() -> ExprPtr { return ParseExpr(predicate_proto); @@ -220,7 +220,8 @@ ProtoParser::RetrievePlanNodeFromProto( }(); node->predicate_ = std::move(expr_opt); } - node->is_count = query.is_count(); + node->is_count_ = query.is_count(); + node->limit_ = query.limit(); } return node; }(); diff --git a/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp b/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp index 96e96573a21fd..d34a4ce0188ef 100644 --- a/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp +++ b/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp @@ -148,12 +148,12 @@ ExecPlanNodeVisitor::visit(RetrievePlanNode& node) { auto active_count = segment->get_active_count(timestamp_); - if (active_count == 0 && !node.is_count) { + if (active_count == 0 && !node.is_count_) { retrieve_result_opt_ = std::move(retrieve_result); return; } - if (active_count == 0 && node.is_count) { + if (active_count == 0 && node.is_count_) { retrieve_result = *(wrap_num_entities(0)); retrieve_result_opt_ = std::move(retrieve_result); return; @@ -161,7 +161,7 @@ ExecPlanNodeVisitor::visit(RetrievePlanNode& node) { BitsetType bitset_holder; // For case that retrieve by expression, bitset will be allocated when expression is being executed. - if (node.is_count) { + if (node.is_count_) { bitset_holder.resize(active_count); } @@ -176,27 +176,27 @@ ExecPlanNodeVisitor::visit(RetrievePlanNode& node) { segment->mask_with_delete(bitset_holder, active_count, timestamp_); // if bitset_holder is all 1's, we got empty result - if (bitset_holder.all() && !node.is_count) { + if (bitset_holder.all() && !node.is_count_) { retrieve_result_opt_ = std::move(retrieve_result); return; } - if (node.is_count) { + if (node.is_count_) { auto cnt = bitset_holder.size() - bitset_holder.count(); retrieve_result = *(wrap_num_entities(cnt)); retrieve_result_opt_ = std::move(retrieve_result); return; } - BitsetView final_view = bitset_holder; - auto seg_offsets = - GetExprUsePkIndex() && IsTermExpr(node.predicate_.value().get()) - ? segment->search_ids( - final_view, expr_cached_pk_id_offsets_, timestamp_) - : segment->search_ids(bitset_holder.flip(), timestamp_); - retrieve_result.result_offsets_.assign( - (int64_t*)seg_offsets.data(), - (int64_t*)seg_offsets.data() + seg_offsets.size()); + bitset_holder.flip(); + if (GetExprUsePkIndex() && IsTermExpr(node.predicate_.value().get())) { + segment->search_ids_filter( + bitset_holder, expr_cached_pk_id_offsets_, timestamp_); + } else { + segment->search_ids_filter(bitset_holder, timestamp_); + } + retrieve_result.result_offsets_ = + segment->find_first(node.limit_, bitset_holder); retrieve_result_opt_ = std::move(retrieve_result); } diff --git a/internal/core/src/segcore/InsertRecord.h b/internal/core/src/segcore/InsertRecord.h index a85aad902ce31..6e98c0b3698a3 100644 --- a/internal/core/src/segcore/InsertRecord.h +++ b/internal/core/src/segcore/InsertRecord.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "TimestampIndex.h" #include "common/Schema.h" @@ -29,6 +30,12 @@ namespace milvus::segcore { +constexpr int64_t Unlimited = -1; +constexpr int64_t NoLimit = 0; +// If `bitset_count * 100` > `total_count * BruteForceSelectivity`, we use pk index. +// Otherwise, we use bruteforce to retrieve all the pks and then sort them. +constexpr int64_t BruteForceSelectivity = 10; + class OffsetMap { public: virtual ~OffsetMap() = default; @@ -44,10 +51,15 @@ class OffsetMap { virtual bool empty() const = 0; + + using OffsetType = int64_t; + // TODO: in fact, we can retrieve the pk here. Not sure which way is more efficient. + virtual std::vector + find_first(int64_t limit, const BitsetType& bitset) const = 0; }; template -class OffsetHashMap : public OffsetMap { +class OffsetOrderedMap : public OffsetMap { public: std::vector find(const PkType& pk) const override { @@ -64,7 +76,7 @@ class OffsetHashMap : public OffsetMap { void seal() override { PanicInfo( - "OffsetHashMap used for growing segment could not be sealed."); + "OffsetOrderedMap used for growing segment could not be sealed."); } bool @@ -72,8 +84,41 @@ class OffsetHashMap : public OffsetMap { return map_.empty(); } + std::vector + find_first(int64_t limit, const BitsetType& bitset) const override { + if (limit == Unlimited || limit == NoLimit) { + limit = map_.size(); + } + + // TODO: we can't retrieve pk by offset very conveniently. + // Selectivity should be done outside. + return find_first_by_index(limit, bitset); + } + + private: + std::vector + find_first_by_index(int64_t limit, const BitsetType& bitset) const { + std::vector seg_offsets; + seg_offsets.reserve(limit); + int64_t hit_num = 0; // avoid counting the number everytime. + auto cnt = bitset.count(); + for (auto it = map_.begin(); it != map_.end(); it++) { + if (hit_num >= limit || hit_num >= cnt) { + break; + } + for (auto seg_offset : it->second) { + if (bitset[seg_offset]) { + seg_offsets.push_back(seg_offset); + hit_num++; + } + } + } + return seg_offsets; + } + private: - std::unordered_map> map_; + using OrderedMap = std::map, std::less<>>; + OrderedMap map_; }; template @@ -81,8 +126,7 @@ class OffsetOrderedArray : public OffsetMap { public: std::vector find(const PkType& pk) const override { - if (!is_sealed) - PanicInfo("OffsetOrderedArray could not search before seal"); + check_search(); const T& target = std::get(pk); auto it = @@ -118,6 +162,44 @@ class OffsetOrderedArray : public OffsetMap { return array_.empty(); } + std::vector + find_first(int64_t limit, const BitsetType& bitset) const override { + check_search(); + + if (limit == Unlimited || limit == NoLimit) { + limit = array_.size(); + } + + // TODO: we can't retrieve pk by offset very conveniently. + // Selectivity should be done outside. + return find_first_by_index(limit, bitset); + } + + private: + std::vector + find_first_by_index(int64_t limit, const BitsetType& bitset) const { + std::vector seg_offsets; + seg_offsets.reserve(limit); + int64_t hit_num = 0; // avoid counting the number everytime. + auto cnt = bitset.count(); + for (auto it = array_.begin(); it != array_.end(); it++) { + if (hit_num >= limit || hit_num >= cnt) { + break; + } + if (bitset[it->second]) { + seg_offsets.push_back(it->second); + hit_num++; + } + } + return seg_offsets; + } + + void + check_search() const { + AssertInfo(is_sealed, + "OffsetOrderedArray could not search before seal"); + } + private: bool is_sealed = false; std::vector> array_; @@ -154,7 +236,7 @@ struct InsertRecord { std::make_unique>(); else pk2offset_ = - std::make_unique>(); + std::make_unique>(); break; } case DataType::VARCHAR: { @@ -162,8 +244,8 @@ struct InsertRecord { pk2offset_ = std::make_unique< OffsetOrderedArray>(); else - pk2offset_ = - std::make_unique>(); + pk2offset_ = std::make_unique< + OffsetOrderedMap>(); break; } default: { diff --git a/internal/core/src/segcore/SegmentGrowingImpl.cpp b/internal/core/src/segcore/SegmentGrowingImpl.cpp index d61f08578186a..6cc289f37441b 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.cpp +++ b/internal/core/src/segcore/SegmentGrowingImpl.cpp @@ -474,55 +474,6 @@ SegmentGrowingImpl::bulk_subscript(SystemFieldType system_type, } } -std::vector -SegmentGrowingImpl::search_ids(const BitsetType& bitset, - Timestamp timestamp) const { - std::vector res_offsets; - for (int i = bitset.find_first(); i < bitset.size(); - i = bitset.find_next(i)) { - if (i == BitsetType::npos) { - return res_offsets; - } - auto offset = SegOffset(i); - if (insert_record_.timestamps_[offset.get()] <= timestamp) { - res_offsets.push_back(offset); - } - } - return res_offsets; -} - -std::vector -SegmentGrowingImpl::search_ids(const BitsetView& bitset, - Timestamp timestamp) const { - std::vector res_offsets; - - for (int i = 0; i < bitset.size(); ++i) { - if (!bitset.test(i)) { - auto offset = SegOffset(i); - if (insert_record_.timestamps_[offset.get()] <= timestamp) { - res_offsets.push_back(offset); - } - } - } - return res_offsets; -} - -std::vector -SegmentGrowingImpl::search_ids(const BitsetView& bitset, - const std::vector& offsets, - Timestamp timestamp) const { - std::vector res_offsets; - - for (auto& offset : offsets) { - if (!bitset.test(offset)) { - if (insert_record_.timestamps_[offset] <= timestamp) { - res_offsets.push_back(SegOffset(offset)); - } - } - } - return res_offsets; -} - std::pair, std::vector> SegmentGrowingImpl::search_ids(const IdArray& id_array, Timestamp timestamp) const { diff --git a/internal/core/src/segcore/SegmentGrowingImpl.h b/internal/core/src/segcore/SegmentGrowingImpl.h index d7775949bd1e3..7b6dbee2105a6 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.h +++ b/internal/core/src/segcore/SegmentGrowingImpl.h @@ -213,17 +213,6 @@ class SegmentGrowingImpl : public SegmentGrowing { std::pair, std::vector> search_ids(const IdArray& id_array, Timestamp timestamp) const override; - std::vector - search_ids(const BitsetType& view, Timestamp timestamp) const override; - - std::vector - search_ids(const BitsetView& view, Timestamp timestamp) const override; - - std::vector - search_ids(const BitsetView& view, - const std::vector& offsets, - Timestamp timestamp) const override; - bool HasIndex(FieldId field_id) const override { return true; @@ -245,6 +234,11 @@ class SegmentGrowingImpl : public SegmentGrowing { return true; } + std::vector + find_first(int64_t limit, const BitsetType& bitset) const override { + return insert_record_.pk2offset_->find_first(limit, bitset); + } + protected: int64_t num_chunk() const override; @@ -257,6 +251,11 @@ class SegmentGrowingImpl : public SegmentGrowing { Assert(plan); } + const ConcurrentVector& + get_timestamps() const override { + return insert_record_.timestamps_; + } + private: SegcoreConfig segcore_config_; SchemaPtr schema_; diff --git a/internal/core/src/segcore/SegmentInterface.cpp b/internal/core/src/segcore/SegmentInterface.cpp index 0184af0e5c149..39f7a6b3295ce 100644 --- a/internal/core/src/segcore/SegmentInterface.cpp +++ b/internal/core/src/segcore/SegmentInterface.cpp @@ -84,7 +84,7 @@ SegmentInternalInterface::Retrieve(const query::RetrievePlan* plan, auto retrieve_results = visitor.get_retrieve_result(*plan->plan_node_); retrieve_results.segment_ = (void*)this; - if (plan->plan_node_->is_count) { + if (plan->plan_node_->is_count_) { AssertInfo(retrieve_results.field_data_.size() == 1, "count result should only have one column"); *results->add_fields_data() = retrieve_results.field_data_[0]; @@ -165,7 +165,7 @@ SegmentInternalInterface::get_real_count() const { #endif auto plan = std::make_unique(get_schema()); plan->plan_node_ = std::make_unique(); - plan->plan_node_->is_count = true; + plan->plan_node_->is_count_ = true; auto res = Retrieve(plan.get(), MAX_TIMESTAMP); AssertInfo(res->fields_data().size() == 1, "count result should only have one column"); @@ -178,4 +178,35 @@ SegmentInternalInterface::get_real_count() const { return res->fields_data()[0].scalars().long_data().data(0); } +void +SegmentInternalInterface::search_ids_filter(BitsetType& bitset, + Timestamp timestamp) const { + auto& timestamps = get_timestamps(); + for (int offset = bitset.find_first(); offset < bitset.size(); + offset = bitset.find_next(offset)) { + if (offset == BitsetType::npos) { + return; + } + // You can't see an entity which is inserted after the point when you search. + if (timestamps[offset] > timestamp) { + bitset[offset] = false; + } + } +} + +void +SegmentInternalInterface::search_ids_filter(BitsetType& bitset, + const std::vector& offsets, + Timestamp timestamp) const { + BitsetType bitset_copy = bitset; + bitset.reset(); + auto& timestamps = get_timestamps(); + for (auto& offset : offsets) { + // You can't see an entity which is inserted after the point when you search. + if (bitset_copy[offset] && timestamps[offset] <= timestamp) { + bitset.set(offset, true); + } + } +} + } // namespace milvus::segcore diff --git a/internal/core/src/segcore/SegmentInterface.h b/internal/core/src/segcore/SegmentInterface.h index f7885daaf1f99..aa4f73a592a8c 100644 --- a/internal/core/src/segcore/SegmentInterface.h +++ b/internal/core/src/segcore/SegmentInterface.h @@ -183,19 +183,19 @@ class SegmentInternalInterface : public SegmentInterface { virtual int64_t get_active_count(Timestamp ts) const = 0; - virtual std::vector - search_ids(const BitsetType& view, Timestamp timestamp) const = 0; + virtual std::pair, std::vector> + search_ids(const IdArray& id_array, Timestamp timestamp) const = 0; - virtual std::vector - search_ids(const BitsetView& view, Timestamp timestamp) const = 0; + void + search_ids_filter(BitsetType& bitset, Timestamp timestamp) const; - virtual std::vector - search_ids(const BitsetView& view, - const std::vector& offsets, - Timestamp timestamp) const = 0; + void + search_ids_filter(BitsetType& bitset, + const std::vector& offsets, + Timestamp timestamp) const; - virtual std::pair, std::vector> - search_ids(const IdArray& id_array, Timestamp timestamp) const = 0; + virtual std::vector + find_first(int64_t limit, const BitsetType& bitset) const = 0; protected: // internal API: return chunk_data in span @@ -222,6 +222,9 @@ class SegmentInternalInterface : public SegmentInterface { virtual void check_search(const query::Plan* plan) const = 0; + virtual const ConcurrentVector& + get_timestamps() const = 0; + protected: mutable std::shared_mutex mutex_; }; diff --git a/internal/core/src/segcore/SegmentSealedImpl.cpp b/internal/core/src/segcore/SegmentSealedImpl.cpp index cefa942946c4c..813e8f2263eda 100644 --- a/internal/core/src/segcore/SegmentSealedImpl.cpp +++ b/internal/core/src/segcore/SegmentSealedImpl.cpp @@ -1005,51 +1005,6 @@ SegmentSealedImpl::Delete(int64_t reserved_offset, // deprecated return Status::OK(); } -std::vector -SegmentSealedImpl::search_ids(const BitsetType& bitset, - Timestamp timestamp) const { - std::vector dst_offset; - for (int offset = bitset.find_first(); offset < bitset.size(); - offset = bitset.find_next(offset)) { - if (offset == BitsetType::npos) { - return dst_offset; - } - if (insert_record_.timestamps_[offset] <= timestamp) { - dst_offset.emplace_back(offset); - } - } - return dst_offset; -} - -std::vector -SegmentSealedImpl::search_ids(const BitsetView& bitset, - Timestamp timestamp) const { - std::vector dst_offset; - for (int offset = 0; offset < bitset.size(); offset++) { - if (!bitset.test(offset)) { - if (insert_record_.timestamps_[offset] <= timestamp) { - dst_offset.emplace_back(offset); - } - } - } - return dst_offset; -} - -std::vector -SegmentSealedImpl::search_ids(const BitsetView& bitset, - const std::vector& offsets, - Timestamp timestamp) const { - std::vector dst_offset; - for (auto& offset : offsets) { - if (!bitset.test(offset)) { - if (insert_record_.timestamps_[offset] <= timestamp) { - dst_offset.emplace_back(offset); - } - } - } - return dst_offset; -} - std::string SegmentSealedImpl::debug() const { std::string log_str; diff --git a/internal/core/src/segcore/SegmentSealedImpl.h b/internal/core/src/segcore/SegmentSealedImpl.h index cbfc8d76e3150..a65ba99437f6b 100644 --- a/internal/core/src/segcore/SegmentSealedImpl.h +++ b/internal/core/src/segcore/SegmentSealedImpl.h @@ -110,6 +110,11 @@ class SegmentSealedImpl : public SegmentSealed { const IdArray* pks, const Timestamp* timestamps) override; + std::vector + find_first(int64_t limit, const BitsetType& bitset) const override { + return insert_record_.pk2offset_->find_first(limit, bitset); + } + protected: // blob and row_count SpanBase @@ -139,6 +144,11 @@ class SegmentSealedImpl : public SegmentSealed { int64_t get_active_count(Timestamp ts) const override; + const ConcurrentVector& + get_timestamps() const override { + return insert_record_.timestamps_; + } + private: template static void @@ -203,17 +213,6 @@ class SegmentSealedImpl : public SegmentSealed { std::pair, std::vector> search_ids(const IdArray& id_array, Timestamp timestamp) const override; - std::vector - search_ids(const BitsetView& view, Timestamp timestamp) const override; - - std::vector - search_ids(const BitsetView& view, - const std::vector& offsets, - Timestamp timestamp) const override; - - std::vector - search_ids(const BitsetType& view, Timestamp timestamp) const override; - void LoadVecIndex(const LoadIndexInfo& info); diff --git a/internal/core/unittest/CMakeLists.txt b/internal/core/unittest/CMakeLists.txt index 56922f4de4cb3..2cd34beae242b 100644 --- a/internal/core/unittest/CMakeLists.txt +++ b/internal/core/unittest/CMakeLists.txt @@ -51,6 +51,8 @@ set(MILVUS_TEST_FILES test_local_chunk_manager.cpp test_disk_file_manager_test.cpp test_integer_overflow.cpp + test_offset_ordered_map.cpp + test_offset_ordered_array.cpp ) if ( BUILD_DISK_ANN STREQUAL "ON" ) diff --git a/internal/core/unittest/test_offset_ordered_array.cpp b/internal/core/unittest/test_offset_ordered_array.cpp new file mode 100644 index 0000000000000..a5effbd540b19 --- /dev/null +++ b/internal/core/unittest/test_offset_ordered_array.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2019-2020 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under the License + +#include +#include +#include "segcore/InsertRecord.h" + +using namespace milvus; +using namespace milvus::segcore; + +template +class TypedOffsetOrderedArrayTest : public testing::Test { + public: + void + SetUp() override { + er = std::default_random_engine(42); + } + + void + TearDown() override { + } + + protected: + void + insert(T pk) { + map_.insert(pk, offset_++); + data_.push_back(pk); + std::sort(data_.begin(), data_.end()); + } + + void + seal() { + map_.seal(); + } + + std::vector + random_generate(int num) { + std::vector res; + for (int i = 0; i < num; i++) { + if constexpr (std::is_same_v) { + res.push_back(std::to_string(er())); + } else { + res.push_back(static_cast(er())); + } + } + return res; + } + + protected: + int64_t offset_ = 0; + std::vector data_; + milvus::segcore::OffsetOrderedArray map_; + std::default_random_engine er; +}; + +using TypeOfPks = testing::Types; +TYPED_TEST_CASE_P(TypedOffsetOrderedArrayTest); + +TYPED_TEST_P(TypedOffsetOrderedArrayTest, find_first) { + std::vector offsets; + + // not sealed. + ASSERT_ANY_THROW(this->map_.find_first(Unlimited, {})); + + // insert 10 entities. + int num = 10; + auto data = this->random_generate(num); + for (const auto& x : data) { + this->insert(x); + } + + // seal. + this->seal(); + + // all is satisfied. + BitsetType all(num); + all.set(); + offsets = this->map_.find_first(num / 2, all); + ASSERT_EQ(num / 2, offsets.size()); + for (int i = 1; i < offsets.size(); i++) { + ASSERT_TRUE(data[offsets[i - 1]] <= data[offsets[i]]); + } + offsets = this->map_.find_first(Unlimited, all); + ASSERT_EQ(num, offsets.size()); + for (int i = 1; i < offsets.size(); i++) { + ASSERT_TRUE(data[offsets[i - 1]] <= data[offsets[i]]); + } + + // none is satisfied. + BitsetType none(num); + none.reset(); + offsets = this->map_.find_first(num / 2, none); + ASSERT_EQ(0, offsets.size()); + offsets = this->map_.find_first(NoLimit, none); + ASSERT_EQ(0, offsets.size()); +} + +REGISTER_TYPED_TEST_CASE_P(TypedOffsetOrderedArrayTest, find_first); +INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TypedOffsetOrderedArrayTest, TypeOfPks); diff --git a/internal/core/unittest/test_offset_ordered_map.cpp b/internal/core/unittest/test_offset_ordered_map.cpp new file mode 100644 index 0000000000000..29b2c505b0c98 --- /dev/null +++ b/internal/core/unittest/test_offset_ordered_map.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2019-2020 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under the License + +#include +#include +#include "segcore/InsertRecord.h" + +using namespace milvus; +using namespace milvus::segcore; + +template +class TypedOffsetOrderedMapTest : public testing::Test { + public: + void + SetUp() override { + er = std::default_random_engine(42); + } + + void + TearDown() override { + } + + protected: + void + insert(T pk) { + map_.insert(pk, offset_++); + data_.push_back(pk); + std::sort(data_.begin(), data_.end()); + } + + std::vector + random_generate(int num) { + std::vector res; + for (int i = 0; i < num; i++) { + if constexpr (std::is_same_v) { + res.push_back(std::to_string(er())); + } else { + res.push_back(static_cast(er())); + } + } + return res; + } + + protected: + int64_t offset_ = 0; + std::vector data_; + milvus::segcore::OffsetOrderedMap map_; + std::default_random_engine er; +}; + +using TypeOfPks = testing::Types; +TYPED_TEST_CASE_P(TypedOffsetOrderedMapTest); + +TYPED_TEST_P(TypedOffsetOrderedMapTest, find_first) { + std::vector offsets; + + // no data. + offsets = this->map_.find_first(Unlimited, {}); + ASSERT_EQ(0, offsets.size()); + + // insert 10 entities. + int num = 10; + auto data = this->random_generate(num); + for (const auto& x : data) { + this->insert(x); + } + + // all is satisfied. + BitsetType all(num); + all.set(); + offsets = this->map_.find_first(num / 2, all); + ASSERT_EQ(num / 2, offsets.size()); + for (int i = 1; i < offsets.size(); i++) { + ASSERT_TRUE(data[offsets[i - 1]] <= data[offsets[i]]); + } + offsets = this->map_.find_first(Unlimited, all); + ASSERT_EQ(num, offsets.size()); + for (int i = 1; i < offsets.size(); i++) { + ASSERT_TRUE(data[offsets[i - 1]] <= data[offsets[i]]); + } + + // none is satisfied. + BitsetType none(num); + none.reset(); + offsets = this->map_.find_first(num / 2, none); + ASSERT_EQ(0, offsets.size()); + offsets = this->map_.find_first(NoLimit, none); + ASSERT_EQ(0, offsets.size()); +} + +REGISTER_TYPED_TEST_CASE_P(TypedOffsetOrderedMapTest, find_first); +INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TypedOffsetOrderedMapTest, TypeOfPks); diff --git a/internal/proto/plan.proto b/internal/proto/plan.proto index a3825fc60fa3f..741a941951e72 100644 --- a/internal/proto/plan.proto +++ b/internal/proto/plan.proto @@ -159,6 +159,7 @@ message VectorANNS { message QueryPlanNode { Expr predicates = 1; bool is_count = 2; + int64 limit = 3; }; message PlanNode { diff --git a/internal/proto/planpb/plan.pb.go b/internal/proto/planpb/plan.pb.go index a775787bebe44..ccf85bd10644b 100644 --- a/internal/proto/planpb/plan.pb.go +++ b/internal/proto/planpb/plan.pb.go @@ -1346,6 +1346,7 @@ func (m *VectorANNS) GetPlaceholderTag() string { type QueryPlanNode struct { Predicates *Expr `protobuf:"bytes,1,opt,name=predicates,proto3" json:"predicates,omitempty"` IsCount bool `protobuf:"varint,2,opt,name=is_count,json=isCount,proto3" json:"is_count,omitempty"` + Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1390,6 +1391,13 @@ func (m *QueryPlanNode) GetIsCount() bool { return false } +func (m *QueryPlanNode) GetLimit() int64 { + if m != nil { + return m.Limit + } + return 0 +} + type PlanNode struct { // Types that are valid to be assigned to Node: // *PlanNode_VectorAnns @@ -1522,102 +1530,103 @@ func init() { func init() { proto.RegisterFile("plan.proto", fileDescriptor_2d655ab2f7683c23) } var fileDescriptor_2d655ab2f7683c23 = []byte{ - // 1542 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcd, 0x72, 0xdc, 0x4a, - 0x15, 0x1e, 0xcd, 0xaf, 0x74, 0x34, 0x1e, 0x2b, 0xda, 0xe0, 0x24, 0xdc, 0xd8, 0x88, 0x5b, 0x5c, - 0x73, 0xa9, 0xd8, 0x75, 0xb9, 0x97, 0x84, 0x84, 0x0a, 0xf8, 0x37, 0x9e, 0xa9, 0x24, 0xf6, 0xa0, - 0x38, 0x5e, 0xb0, 0x51, 0xf5, 0x48, 0x6d, 0x4f, 0x57, 0x34, 0xdd, 0x8a, 0xd4, 0x9a, 0x78, 0x5e, - 0x81, 0x1d, 0x0f, 0xc0, 0x8a, 0x05, 0x7b, 0x96, 0x14, 0x55, 0xbc, 0x00, 0x0b, 0x96, 0xec, 0x79, - 0x02, 0x8a, 0x17, 0xa0, 0xfa, 0xb4, 0xe6, 0xcf, 0x35, 0x13, 0x8f, 0x21, 0x55, 0xec, 0xba, 0x4f, - 0x9f, 0xf3, 0x9d, 0xdf, 0x3e, 0x7d, 0x1a, 0x20, 0x89, 0x09, 0xdf, 0x49, 0x52, 0x21, 0x85, 0x7b, - 0x6f, 0xc0, 0xe2, 0x61, 0x9e, 0xe9, 0xdd, 0x8e, 0x3a, 0x78, 0xd0, 0xcc, 0xc2, 0x3e, 0x1d, 0x10, - 0x4d, 0xf2, 0x7e, 0x67, 0x40, 0xf3, 0x84, 0x72, 0x9a, 0xb2, 0xf0, 0x82, 0xc4, 0x39, 0x75, 0x1f, - 0x82, 0xd9, 0x13, 0x22, 0x0e, 0x86, 0x24, 0xde, 0x30, 0xb6, 0x8c, 0x6d, 0xb3, 0x5d, 0xf2, 0x1b, - 0x8a, 0x72, 0x41, 0x62, 0xf7, 0x0b, 0xb0, 0x18, 0x97, 0x4f, 0xbe, 0xc3, 0xd3, 0xf2, 0x96, 0xb1, - 0x5d, 0x69, 0x97, 0x7c, 0x13, 0x49, 0xc5, 0xf1, 0x65, 0x2c, 0x88, 0xc4, 0xe3, 0xca, 0x96, 0xb1, - 0x6d, 0xa8, 0x63, 0x24, 0xa9, 0xe3, 0x4d, 0x80, 0x4c, 0xa6, 0x8c, 0x5f, 0xe1, 0x79, 0x75, 0xcb, - 0xd8, 0xb6, 0xda, 0x25, 0xdf, 0xd2, 0xb4, 0x0b, 0x12, 0x1f, 0xd4, 0xa0, 0x32, 0x24, 0xb1, 0xf7, - 0x5b, 0x03, 0xac, 0x5f, 0xe7, 0x34, 0x1d, 0x75, 0xf8, 0xa5, 0x70, 0x5d, 0xa8, 0x4a, 0x91, 0xbc, - 0x47, 0x63, 0x2a, 0x3e, 0xae, 0xdd, 0x4d, 0xb0, 0x07, 0x54, 0xa6, 0x2c, 0x0c, 0xe4, 0x28, 0xa1, - 0xa8, 0xca, 0xf2, 0x41, 0x93, 0xce, 0x47, 0x09, 0x75, 0x7f, 0x08, 0x6b, 0x19, 0x25, 0x69, 0xd8, - 0x0f, 0x12, 0x92, 0x92, 0x41, 0xa6, 0xb5, 0xf9, 0x4d, 0x4d, 0xec, 0x22, 0x4d, 0x31, 0xa5, 0x22, - 0xe7, 0x51, 0x10, 0xd1, 0x90, 0x0d, 0x48, 0xbc, 0x51, 0x43, 0x15, 0x4d, 0x24, 0x1e, 0x69, 0x9a, - 0xf7, 0x2f, 0x03, 0xe0, 0x50, 0xc4, 0xf9, 0x80, 0xa3, 0x35, 0xf7, 0xc1, 0xbc, 0x64, 0x34, 0x8e, - 0x02, 0x16, 0x15, 0x16, 0x35, 0x70, 0xdf, 0x89, 0xdc, 0xe7, 0x60, 0x45, 0x44, 0x12, 0x6d, 0x92, - 0x0a, 0x4e, 0xeb, 0xa7, 0x5f, 0xec, 0xcc, 0xc5, 0xbf, 0x88, 0xfc, 0x11, 0x91, 0x44, 0x59, 0xe9, - 0x9b, 0x51, 0xb1, 0x72, 0xbf, 0x84, 0x16, 0xcb, 0x82, 0x24, 0x65, 0x03, 0x92, 0x8e, 0x82, 0xf7, - 0x74, 0x84, 0x3e, 0x99, 0x7e, 0x93, 0x65, 0x5d, 0x4d, 0x7c, 0x45, 0x47, 0xee, 0x43, 0xb0, 0x58, - 0x16, 0x90, 0x5c, 0x8a, 0xce, 0x11, 0x7a, 0x64, 0xfa, 0x26, 0xcb, 0xf6, 0x71, 0xaf, 0x62, 0xc2, - 0x69, 0x26, 0x69, 0x14, 0x24, 0x44, 0xf6, 0x37, 0x6a, 0x5b, 0x15, 0x15, 0x13, 0x4d, 0xea, 0x12, - 0xd9, 0x77, 0xb7, 0xc1, 0x51, 0x3a, 0x48, 0x2a, 0x99, 0x64, 0x82, 0xa3, 0x96, 0x3a, 0x82, 0xb4, - 0x58, 0xd6, 0x1d, 0x93, 0x5f, 0xd1, 0x91, 0xf7, 0xab, 0xb1, 0xcb, 0xc7, 0xd7, 0x49, 0xea, 0x7e, - 0x03, 0x55, 0xc6, 0x2f, 0x05, 0xba, 0x6b, 0xdf, 0x74, 0x09, 0x6b, 0x6d, 0x1a, 0x1f, 0x1f, 0x59, - 0x15, 0xc0, 0xf1, 0x35, 0xcb, 0x64, 0xf6, 0xdf, 0x02, 0x1c, 0x80, 0x85, 0xe5, 0x88, 0xf2, 0x3f, - 0x83, 0xda, 0x50, 0x6d, 0x0a, 0x80, 0xcd, 0x05, 0x00, 0xb3, 0x25, 0xec, 0x6b, 0x6e, 0xef, 0x4f, - 0x06, 0xb4, 0xde, 0x71, 0x92, 0x8e, 0x7c, 0xc2, 0xaf, 0x34, 0xd2, 0x2f, 0xc1, 0x0e, 0x51, 0x55, - 0xb0, 0xba, 0x41, 0x10, 0x4e, 0xb3, 0xff, 0x63, 0x28, 0x8b, 0xa4, 0xc8, 0xed, 0xfd, 0x05, 0x62, - 0x67, 0x09, 0xe6, 0xb5, 0x2c, 0x92, 0xa9, 0xd1, 0x95, 0x3b, 0x19, 0xfd, 0xc7, 0x32, 0xac, 0x1f, - 0xb0, 0xcf, 0x6b, 0xf5, 0x57, 0xb0, 0x1e, 0x8b, 0x8f, 0x34, 0x0d, 0x18, 0x0f, 0xe3, 0x3c, 0x63, - 0x43, 0x5d, 0x9e, 0xa6, 0xdf, 0x42, 0x72, 0x67, 0x4c, 0x55, 0x8c, 0x79, 0x92, 0xcc, 0x31, 0xea, - 0x32, 0x6c, 0x21, 0x79, 0xca, 0xb8, 0x07, 0xb6, 0x46, 0xd4, 0x2e, 0x56, 0x57, 0x73, 0x11, 0x50, - 0x46, 0xb7, 0x99, 0x3d, 0xb0, 0xb5, 0x2a, 0x8d, 0x50, 0x5b, 0x11, 0x01, 0x65, 0x70, 0xed, 0xfd, - 0xcd, 0x00, 0xfb, 0x50, 0x0c, 0x12, 0x92, 0xea, 0x28, 0x9d, 0x80, 0x13, 0xd3, 0x4b, 0x19, 0xdc, - 0x39, 0x54, 0x2d, 0x25, 0x36, 0x73, 0xc5, 0x3b, 0x70, 0x2f, 0x65, 0x57, 0xfd, 0x79, 0xa4, 0xf2, - 0x2a, 0x48, 0xeb, 0x28, 0x77, 0x78, 0xb3, 0x5e, 0x2a, 0x2b, 0xd4, 0x8b, 0xf7, 0x07, 0x03, 0xcc, - 0x73, 0x9a, 0x0e, 0x3e, 0x4b, 0xc6, 0x9f, 0x42, 0x1d, 0xe3, 0x9a, 0x6d, 0x94, 0xb7, 0x2a, 0xab, - 0x04, 0xb6, 0x60, 0x77, 0x1f, 0x81, 0xcd, 0xb2, 0x80, 0xf1, 0x00, 0x9b, 0x5a, 0x91, 0x7d, 0x8b, - 0x65, 0x1d, 0xfe, 0x52, 0x11, 0xd4, 0x73, 0x61, 0xe1, 0x9d, 0x42, 0x33, 0xbf, 0x43, 0xf7, 0x0c, - 0x74, 0xef, 0xcb, 0x05, 0x2a, 0x26, 0x9c, 0x7a, 0x75, 0x96, 0xe0, 0xcd, 0x78, 0x0c, 0xb5, 0xb0, - 0xcf, 0xe2, 0xa8, 0x88, 0xe9, 0xf7, 0x16, 0x08, 0x2a, 0x19, 0x5f, 0x73, 0x79, 0x9b, 0xd0, 0x28, - 0xa4, 0x5d, 0x1b, 0x1a, 0x1d, 0x3e, 0x24, 0x31, 0x8b, 0x9c, 0x92, 0xdb, 0x80, 0xca, 0xa9, 0x90, - 0x8e, 0xe1, 0xfd, 0xc3, 0x00, 0xd0, 0x57, 0x06, 0x8d, 0x7a, 0x32, 0x63, 0xd4, 0x8f, 0x16, 0x60, - 0x4f, 0x59, 0x8b, 0x65, 0x61, 0xd6, 0x4f, 0xa0, 0xaa, 0x0a, 0xe1, 0x36, 0xab, 0x90, 0x49, 0xf9, - 0x80, 0xb9, 0x2e, 0x6e, 0xf7, 0x72, 0x1f, 0x90, 0xcb, 0x7b, 0x02, 0xe6, 0x58, 0xd7, 0xbc, 0x13, - 0x2d, 0x80, 0xd7, 0xe2, 0x8a, 0x85, 0x24, 0xde, 0xe7, 0x91, 0x63, 0xb8, 0x6b, 0x60, 0x15, 0xfb, - 0xb3, 0xd4, 0x29, 0x7b, 0x7f, 0x37, 0x60, 0x4d, 0x0b, 0xee, 0xa7, 0x4c, 0xf6, 0xcf, 0x92, 0xff, - 0xb9, 0x32, 0x9e, 0x81, 0x49, 0x14, 0x54, 0x30, 0xe9, 0x63, 0x8f, 0x16, 0x08, 0x17, 0xda, 0xb0, - 0x38, 0x1b, 0xa4, 0x50, 0x7d, 0x04, 0x6b, 0xfa, 0x5e, 0x88, 0x84, 0xa6, 0x84, 0x47, 0xab, 0x76, - 0xb6, 0x26, 0x4a, 0x9d, 0x69, 0x21, 0xef, 0xf7, 0xc6, 0xb8, 0xc1, 0xa1, 0x12, 0x4c, 0xd9, 0x38, - 0xf4, 0xc6, 0x9d, 0x42, 0x5f, 0x5e, 0x25, 0xf4, 0xee, 0xce, 0xcc, 0x15, 0xbc, 0xcd, 0x55, 0x75, - 0x0f, 0xff, 0x5a, 0x86, 0x07, 0x73, 0x21, 0x3f, 0x1e, 0x92, 0xf8, 0xf3, 0xf5, 0xe2, 0xff, 0x77, - 0xfc, 0x8b, 0x96, 0x54, 0xbd, 0xd3, 0x13, 0x56, 0xbb, 0xd3, 0x13, 0xf6, 0x97, 0x3a, 0x54, 0x31, - 0x56, 0xcf, 0xc1, 0x92, 0x34, 0x1d, 0x04, 0xf4, 0x3a, 0x49, 0x8b, 0x48, 0x3d, 0x5c, 0x80, 0x31, - 0xee, 0x7a, 0x6a, 0x56, 0x94, 0xe3, 0x0e, 0xf8, 0x02, 0x20, 0x57, 0x49, 0xd0, 0xc2, 0x3a, 0xd5, - 0xdf, 0xff, 0x54, 0x8b, 0x51, 0x93, 0x64, 0x3e, 0x69, 0x02, 0x7b, 0x60, 0xf7, 0xd8, 0x54, 0xbe, - 0xb2, 0x34, 0x4d, 0xd3, 0x6e, 0xd0, 0x2e, 0xf9, 0xd0, 0x9b, 0xb6, 0x91, 0x43, 0x68, 0x86, 0xfa, - 0x75, 0xd1, 0x10, 0xfa, 0x8d, 0x7b, 0xb4, 0x30, 0xd3, 0x93, 0x47, 0xa8, 0x5d, 0xf2, 0xed, 0x70, - 0xe6, 0x4d, 0x7a, 0x03, 0x8e, 0xf6, 0x22, 0x55, 0x05, 0xa4, 0x81, 0x74, 0x30, 0x7f, 0xb0, 0xcc, - 0x97, 0x49, 0xa9, 0xb5, 0x4b, 0x7e, 0x2b, 0x9f, 0x1f, 0x04, 0xba, 0x70, 0xaf, 0xf0, 0x6a, 0x06, - 0xaf, 0x8e, 0x78, 0xde, 0x52, 0xdf, 0x66, 0x01, 0xd7, 0x7b, 0x37, 0x46, 0x0b, 0x09, 0x9b, 0x05, - 0xe2, 0xb8, 0x2a, 0x03, 0x3a, 0x24, 0xf1, 0x2c, 0x7e, 0x03, 0xf1, 0x1f, 0x2f, 0xc5, 0x5f, 0x74, - 0x4d, 0xda, 0x25, 0xff, 0x41, 0x6f, 0xf9, 0x25, 0x9a, 0xfa, 0xa1, 0xb5, 0xa2, 0x1e, 0xf3, 0x16, - 0x3f, 0x26, 0xed, 0x62, 0xea, 0xc7, 0xb4, 0x83, 0xbc, 0x00, 0xc0, 0xe2, 0xd3, 0x50, 0xd6, 0xd2, - 0x72, 0x99, 0x0c, 0x95, 0xaa, 0x5c, 0x86, 0x93, 0x09, 0x73, 0x6f, 0x72, 0xab, 0x51, 0x1e, 0x6e, - 0xb9, 0xd5, 0xe3, 0x72, 0x09, 0xa7, 0x43, 0xf2, 0x1e, 0xd8, 0x14, 0x27, 0x5e, 0x8d, 0x60, 0x2f, - 0x45, 0x98, 0xce, 0xc5, 0x0a, 0x81, 0x4e, 0x76, 0x07, 0x75, 0xa8, 0x2a, 0x51, 0xef, 0x9f, 0x06, - 0xc0, 0x05, 0x0d, 0xa5, 0x48, 0xf7, 0x4f, 0x4f, 0xdf, 0x16, 0x33, 0xbf, 0xf6, 0x57, 0x7f, 0xc8, - 0xd4, 0xcc, 0xaf, 0x43, 0x32, 0xf7, 0x1b, 0x29, 0xcf, 0xff, 0x46, 0x9e, 0x02, 0x24, 0x29, 0x8d, - 0x58, 0x48, 0x24, 0xcd, 0x6e, 0x7b, 0xa6, 0x66, 0x58, 0xdd, 0x5f, 0x00, 0x7c, 0x50, 0x9f, 0x2f, - 0xdd, 0xe0, 0xaa, 0x4b, 0x43, 0x39, 0xf9, 0xa1, 0xf9, 0xd6, 0x87, 0xc9, 0x67, 0xed, 0x2b, 0x58, - 0x4f, 0x62, 0x12, 0xd2, 0xbe, 0x88, 0x23, 0x9a, 0x06, 0x92, 0x5c, 0x61, 0xbd, 0x5b, 0x7e, 0x6b, - 0x86, 0x7c, 0x4e, 0xae, 0xbc, 0x10, 0xd6, 0x10, 0xa0, 0x1b, 0x13, 0x7e, 0x2a, 0x22, 0x7a, 0xc3, - 0x5e, 0x63, 0x75, 0x7b, 0xef, 0x83, 0xc9, 0xb2, 0x20, 0x14, 0x39, 0x97, 0xc5, 0x58, 0xdb, 0x60, - 0xd9, 0xa1, 0xda, 0x7a, 0xff, 0x36, 0xc0, 0x9c, 0x28, 0xd8, 0x03, 0x7b, 0x88, 0x61, 0x0d, 0x08, - 0xe7, 0xd9, 0x27, 0x3a, 0xf7, 0x34, 0xf8, 0x2a, 0x43, 0x5a, 0x66, 0x9f, 0xf3, 0xcc, 0x7d, 0x36, - 0x67, 0xe2, 0xa7, 0x9f, 0x1f, 0x25, 0x3a, 0x63, 0xe4, 0xcf, 0xa1, 0x86, 0x41, 0x2a, 0xe2, 0xb9, - 0xb5, 0x2c, 0x9e, 0x63, 0x6b, 0xdb, 0x25, 0x5f, 0x0b, 0xa8, 0x5f, 0x9b, 0xc8, 0x65, 0x92, 0xcb, - 0x60, 0x9c, 0x69, 0x95, 0xcd, 0xca, 0x76, 0xc5, 0x6f, 0x69, 0xfa, 0x4b, 0x9d, 0xf0, 0x4c, 0x15, - 0x10, 0x17, 0x11, 0xfd, 0xfa, 0xcf, 0x06, 0xd4, 0x75, 0x17, 0x9f, 0x9f, 0x35, 0xd6, 0xc1, 0x3e, - 0x49, 0x29, 0x91, 0x34, 0x3d, 0xef, 0x13, 0xee, 0x18, 0xae, 0x03, 0xcd, 0x82, 0x70, 0xfc, 0x21, - 0x27, 0xb1, 0x53, 0x76, 0x9b, 0x60, 0xbe, 0xa6, 0x59, 0x86, 0xe7, 0x15, 0x1c, 0x46, 0x68, 0x96, - 0xe9, 0xc3, 0xaa, 0x6b, 0x41, 0x4d, 0x2f, 0x6b, 0x8a, 0xef, 0x54, 0x48, 0xbd, 0xab, 0x2b, 0xe0, - 0x6e, 0x4a, 0x2f, 0xd9, 0xf5, 0x1b, 0x22, 0xc3, 0xbe, 0xd3, 0x50, 0xc0, 0x5d, 0x91, 0xc9, 0x09, - 0xc5, 0x54, 0xb2, 0x7a, 0x69, 0xa9, 0x25, 0x76, 0x02, 0x07, 0xdc, 0x3a, 0x94, 0x3b, 0xdc, 0xb1, - 0x15, 0xe9, 0x54, 0xc8, 0x0e, 0x77, 0x9a, 0x5f, 0x9f, 0x80, 0x3d, 0xf3, 0xf8, 0x29, 0x07, 0xde, - 0xf1, 0xf7, 0x5c, 0x7c, 0xe4, 0x7a, 0xe2, 0xdb, 0x8f, 0xd4, 0x94, 0xd4, 0x80, 0xca, 0xdb, 0xbc, - 0xe7, 0x94, 0xd5, 0xe2, 0x4d, 0x1e, 0x3b, 0x15, 0xb5, 0x38, 0x62, 0x43, 0xa7, 0x8a, 0x14, 0x11, - 0x39, 0xb5, 0x83, 0x6f, 0x7f, 0xf3, 0xcd, 0x15, 0x93, 0xfd, 0xbc, 0xb7, 0x13, 0x8a, 0xc1, 0xae, - 0x0e, 0xf7, 0x63, 0x26, 0x8a, 0xd5, 0x2e, 0xe3, 0x92, 0xa6, 0x9c, 0xc4, 0xbb, 0x98, 0x81, 0x5d, - 0x95, 0x81, 0xa4, 0xd7, 0xab, 0xe3, 0xee, 0xdb, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x85, - 0x01, 0x1b, 0x43, 0x11, 0x00, 0x00, + // 1554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcd, 0x6e, 0xdb, 0xc6, + 0x13, 0x17, 0x45, 0x7d, 0x90, 0x43, 0x59, 0x66, 0x88, 0x3f, 0xf0, 0x77, 0x92, 0x26, 0x76, 0xd9, + 0xa0, 0x71, 0x53, 0xc4, 0x46, 0x9a, 0x34, 0x69, 0x52, 0xa4, 0xf5, 0x67, 0x2c, 0x21, 0x89, 0xad, + 0x32, 0x8e, 0x0f, 0xbd, 0x10, 0x2b, 0x72, 0x6d, 0x2d, 0x42, 0xed, 0x32, 0xe4, 0x52, 0xb1, 0x5e, + 0xa1, 0xb7, 0x3e, 0x40, 0x4f, 0x3d, 0xf4, 0xde, 0x63, 0x51, 0xa0, 0x2f, 0xd0, 0x43, 0x8f, 0xbd, + 0xf7, 0x09, 0x8a, 0xbe, 0x40, 0xb1, 0xbb, 0xd4, 0x97, 0x21, 0xc5, 0x72, 0x1b, 0xa0, 0xb7, 0xdd, + 0xd9, 0x99, 0xdf, 0x7c, 0xee, 0xec, 0x2c, 0x40, 0x1c, 0x21, 0xba, 0x16, 0x27, 0x8c, 0x33, 0xe7, + 0x52, 0x97, 0x44, 0xbd, 0x2c, 0x55, 0xbb, 0x35, 0x71, 0x70, 0xa5, 0x96, 0x06, 0x1d, 0xdc, 0x45, + 0x8a, 0xe4, 0x7e, 0xab, 0x41, 0x6d, 0x0f, 0x53, 0x9c, 0x90, 0xe0, 0x08, 0x45, 0x19, 0x76, 0xae, + 0x82, 0xd1, 0x66, 0x2c, 0xf2, 0x7b, 0x28, 0x5a, 0xd2, 0x56, 0xb4, 0x55, 0xa3, 0x51, 0xf0, 0xaa, + 0x82, 0x72, 0x84, 0x22, 0xe7, 0x1a, 0x98, 0x84, 0xf2, 0xfb, 0xf7, 0xe4, 0x69, 0x71, 0x45, 0x5b, + 0xd5, 0x1b, 0x05, 0xcf, 0x90, 0xa4, 0xfc, 0xf8, 0x38, 0x62, 0x88, 0xcb, 0x63, 0x7d, 0x45, 0x5b, + 0xd5, 0xc4, 0xb1, 0x24, 0x89, 0xe3, 0x65, 0x80, 0x94, 0x27, 0x84, 0x9e, 0xc8, 0xf3, 0xd2, 0x8a, + 0xb6, 0x6a, 0x36, 0x0a, 0x9e, 0xa9, 0x68, 0x47, 0x28, 0xda, 0x2a, 0x83, 0xde, 0x43, 0x91, 0xfb, + 0x8d, 0x06, 0xe6, 0x57, 0x19, 0x4e, 0xfa, 0x4d, 0x7a, 0xcc, 0x1c, 0x07, 0x4a, 0x9c, 0xc5, 0xaf, + 0xa4, 0x31, 0xba, 0x27, 0xd7, 0xce, 0x32, 0x58, 0x5d, 0xcc, 0x13, 0x12, 0xf8, 0xbc, 0x1f, 0x63, + 0xa9, 0xca, 0xf4, 0x40, 0x91, 0x0e, 0xfb, 0x31, 0x76, 0x3e, 0x80, 0x85, 0x14, 0xa3, 0x24, 0xe8, + 0xf8, 0x31, 0x4a, 0x50, 0x37, 0x55, 0xda, 0xbc, 0x9a, 0x22, 0xb6, 0x24, 0x4d, 0x30, 0x25, 0x2c, + 0xa3, 0xa1, 0x1f, 0xe2, 0x80, 0x74, 0x51, 0xb4, 0x54, 0x96, 0x2a, 0x6a, 0x92, 0xb8, 0xa3, 0x68, + 0xee, 0x9f, 0x1a, 0xc0, 0x36, 0x8b, 0xb2, 0x2e, 0x95, 0xd6, 0x5c, 0x06, 0xe3, 0x98, 0xe0, 0x28, + 0xf4, 0x49, 0x98, 0x5b, 0x54, 0x95, 0xfb, 0x66, 0xe8, 0x3c, 0x02, 0x33, 0x44, 0x1c, 0x29, 0x93, + 0x44, 0x70, 0xea, 0x9f, 0x5c, 0x5b, 0x9b, 0x88, 0x7f, 0x1e, 0xf9, 0x1d, 0xc4, 0x91, 0xb0, 0xd2, + 0x33, 0xc2, 0x7c, 0xe5, 0xdc, 0x80, 0x3a, 0x49, 0xfd, 0x38, 0x21, 0x5d, 0x94, 0xf4, 0xfd, 0x57, + 0xb8, 0x2f, 0x7d, 0x32, 0xbc, 0x1a, 0x49, 0x5b, 0x8a, 0xf8, 0x14, 0xf7, 0x9d, 0xab, 0x60, 0x92, + 0xd4, 0x47, 0x19, 0x67, 0xcd, 0x1d, 0xe9, 0x91, 0xe1, 0x19, 0x24, 0xdd, 0x94, 0x7b, 0x11, 0x13, + 0x8a, 0x53, 0x8e, 0x43, 0x3f, 0x46, 0xbc, 0xb3, 0x54, 0x5e, 0xd1, 0x45, 0x4c, 0x14, 0xa9, 0x85, + 0x78, 0xc7, 0x59, 0x05, 0x5b, 0xe8, 0x40, 0x09, 0x27, 0x9c, 0x30, 0x2a, 0xb5, 0x54, 0x24, 0x48, + 0x9d, 0xa4, 0xad, 0x01, 0xf9, 0x29, 0xee, 0xbb, 0x5f, 0x0e, 0x5c, 0xde, 0x3d, 0x8d, 0x13, 0xe7, + 0x0e, 0x94, 0x08, 0x3d, 0x66, 0xd2, 0x5d, 0xeb, 0xac, 0x4b, 0xb2, 0xd6, 0x46, 0xf1, 0xf1, 0x24, + 0xab, 0x00, 0xd8, 0x3d, 0x25, 0x29, 0x4f, 0xff, 0x29, 0xc0, 0x16, 0x98, 0xb2, 0x1c, 0xa5, 0xfc, + 0xa7, 0x50, 0xee, 0x89, 0x4d, 0x0e, 0xb0, 0x3c, 0x05, 0x60, 0xbc, 0x84, 0x3d, 0xc5, 0xed, 0xfe, + 0xa8, 0x41, 0xfd, 0x25, 0x45, 0x49, 0xdf, 0x43, 0xf4, 0x44, 0x21, 0x7d, 0x01, 0x56, 0x20, 0x55, + 0xf9, 0xf3, 0x1b, 0x04, 0xc1, 0x28, 0xfb, 0x1f, 0x41, 0x91, 0xc5, 0x79, 0x6e, 0x2f, 0x4f, 0x11, + 0x3b, 0x88, 0x65, 0x5e, 0x8b, 0x2c, 0x1e, 0x19, 0xad, 0x5f, 0xc8, 0xe8, 0x1f, 0x8a, 0xb0, 0xb8, + 0x45, 0xde, 0xad, 0xd5, 0x37, 0x61, 0x31, 0x62, 0x6f, 0x70, 0xe2, 0x13, 0x1a, 0x44, 0x59, 0x4a, + 0x7a, 0xaa, 0x3c, 0x0d, 0xaf, 0x2e, 0xc9, 0xcd, 0x01, 0x55, 0x30, 0x66, 0x71, 0x3c, 0xc1, 0xa8, + 0xca, 0xb0, 0x2e, 0xc9, 0x23, 0xc6, 0x0d, 0xb0, 0x14, 0xa2, 0x72, 0xb1, 0x34, 0x9f, 0x8b, 0x20, + 0x65, 0x54, 0x9b, 0xd9, 0x00, 0x4b, 0xa9, 0x52, 0x08, 0xe5, 0x39, 0x11, 0xa4, 0x8c, 0x5c, 0xbb, + 0xbf, 0x6a, 0x60, 0x6d, 0xb3, 0x6e, 0x8c, 0x12, 0x15, 0xa5, 0x3d, 0xb0, 0x23, 0x7c, 0xcc, 0xfd, + 0x0b, 0x87, 0xaa, 0x2e, 0xc4, 0xc6, 0xae, 0x78, 0x13, 0x2e, 0x25, 0xe4, 0xa4, 0x33, 0x89, 0x54, + 0x9c, 0x07, 0x69, 0x51, 0xca, 0x6d, 0x9f, 0xad, 0x17, 0x7d, 0x8e, 0x7a, 0x71, 0xbf, 0xd7, 0xc0, + 0x38, 0xc4, 0x49, 0xf7, 0x9d, 0x64, 0xfc, 0x01, 0x54, 0x64, 0x5c, 0xd3, 0xa5, 0xe2, 0x8a, 0x3e, + 0x4f, 0x60, 0x73, 0x76, 0xe7, 0x3a, 0x58, 0x24, 0xf5, 0x09, 0xf5, 0x65, 0x53, 0xcb, 0xb3, 0x6f, + 0x92, 0xb4, 0x49, 0x9f, 0x08, 0x82, 0x78, 0x2e, 0x4c, 0x79, 0xa7, 0xa4, 0x99, 0xf7, 0xa4, 0x7b, + 0x9a, 0x74, 0xef, 0xc6, 0x14, 0x15, 0x43, 0x4e, 0xb5, 0x3a, 0x88, 0xe5, 0xcd, 0xb8, 0x0d, 0xe5, + 0xa0, 0x43, 0xa2, 0x30, 0x8f, 0xe9, 0xff, 0xa7, 0x08, 0x0a, 0x19, 0x4f, 0x71, 0xb9, 0xcb, 0x50, + 0xcd, 0xa5, 0x1d, 0x0b, 0xaa, 0x4d, 0xda, 0x43, 0x11, 0x09, 0xed, 0x82, 0x53, 0x05, 0x7d, 0x9f, + 0x71, 0x5b, 0x73, 0x7f, 0xd7, 0x00, 0xd4, 0x95, 0x91, 0x46, 0xdd, 0x1f, 0x33, 0xea, 0xc3, 0x29, + 0xd8, 0x23, 0xd6, 0x7c, 0x99, 0x9b, 0xf5, 0x31, 0x94, 0x44, 0x21, 0x9c, 0x67, 0x95, 0x64, 0x12, + 0x3e, 0xc8, 0x5c, 0xe7, 0xb7, 0x7b, 0xb6, 0x0f, 0x92, 0xcb, 0xbd, 0x0f, 0xc6, 0x40, 0xd7, 0xa4, + 0x13, 0x75, 0x80, 0x67, 0xec, 0x84, 0x04, 0x28, 0xda, 0xa4, 0xa1, 0xad, 0x39, 0x0b, 0x60, 0xe6, + 0xfb, 0x83, 0xc4, 0x2e, 0xba, 0xbf, 0x69, 0xb0, 0xa0, 0x04, 0x37, 0x13, 0xc2, 0x3b, 0x07, 0xf1, + 0xbf, 0xae, 0x8c, 0x87, 0x60, 0x20, 0x01, 0xe5, 0x0f, 0xfb, 0xd8, 0xf5, 0x29, 0xc2, 0xb9, 0x36, + 0x59, 0x9c, 0x55, 0x94, 0xab, 0xde, 0x81, 0x05, 0x75, 0x2f, 0x58, 0x8c, 0x13, 0x44, 0xc3, 0x79, + 0x3b, 0x5b, 0x4d, 0x4a, 0x1d, 0x28, 0x21, 0xf7, 0x3b, 0x6d, 0xd0, 0xe0, 0xa4, 0x12, 0x99, 0xb2, + 0x41, 0xe8, 0xb5, 0x0b, 0x85, 0xbe, 0x38, 0x4f, 0xe8, 0x9d, 0xb5, 0xb1, 0x2b, 0x78, 0x9e, 0xab, + 0xe2, 0x1e, 0xfe, 0x52, 0x84, 0x2b, 0x13, 0x21, 0xdf, 0xed, 0xa1, 0xe8, 0xdd, 0xf5, 0xe2, 0xff, + 0x3a, 0xfe, 0x79, 0x4b, 0x2a, 0x5d, 0xe8, 0x09, 0x2b, 0x5f, 0xe8, 0x09, 0xfb, 0xb9, 0x02, 0x25, + 0x19, 0xab, 0x47, 0x60, 0x72, 0x9c, 0x74, 0x7d, 0x7c, 0x1a, 0x27, 0x79, 0xa4, 0xae, 0x4e, 0xc1, + 0x18, 0x74, 0x3d, 0x31, 0x2b, 0xf2, 0x41, 0x07, 0x7c, 0x0c, 0x90, 0x89, 0x24, 0x28, 0x61, 0x95, + 0xea, 0xf7, 0xde, 0xd6, 0x62, 0xc4, 0x24, 0x99, 0x0d, 0x9b, 0xc0, 0x06, 0x58, 0x6d, 0x32, 0x92, + 0xd7, 0x67, 0xa6, 0x69, 0xd4, 0x0d, 0x1a, 0x05, 0x0f, 0xda, 0xa3, 0x36, 0xb2, 0x0d, 0xb5, 0x40, + 0xbd, 0x2e, 0x0a, 0x42, 0xbd, 0x71, 0xd7, 0xa7, 0x66, 0x7a, 0xf8, 0x08, 0x35, 0x0a, 0x9e, 0x15, + 0x8c, 0xbd, 0x49, 0xcf, 0xc1, 0x56, 0x5e, 0x24, 0xa2, 0x80, 0x14, 0x90, 0x0a, 0xe6, 0xfb, 0xb3, + 0x7c, 0x19, 0x96, 0x5a, 0xa3, 0xe0, 0xd5, 0xb3, 0xc9, 0x41, 0xa0, 0x05, 0x97, 0x72, 0xaf, 0xc6, + 0xf0, 0x2a, 0x12, 0xcf, 0x9d, 0xe9, 0xdb, 0x38, 0xe0, 0x62, 0xfb, 0xcc, 0x68, 0xc1, 0x61, 0x39, + 0x47, 0x1c, 0x54, 0xa5, 0x8f, 0x7b, 0x28, 0x1a, 0xc7, 0xaf, 0x4a, 0xfc, 0xdb, 0x33, 0xf1, 0xa7, + 0x5d, 0x93, 0x46, 0xc1, 0xbb, 0xd2, 0x9e, 0x7d, 0x89, 0x46, 0x7e, 0x28, 0xad, 0x52, 0x8f, 0x71, + 0x8e, 0x1f, 0xc3, 0x76, 0x31, 0xf2, 0x63, 0xd4, 0x41, 0x1e, 0x03, 0xc8, 0xe2, 0x53, 0x50, 0xe6, + 0xcc, 0x72, 0x19, 0x0e, 0x95, 0xa2, 0x5c, 0x7a, 0xc3, 0x09, 0x73, 0x63, 0x78, 0xab, 0xa5, 0x3c, + 0x9c, 0x73, 0xab, 0x07, 0xe5, 0x12, 0x8c, 0x86, 0xe4, 0x0d, 0xb0, 0xb0, 0x9c, 0x78, 0x15, 0x82, + 0x35, 0x13, 0x61, 0x34, 0x17, 0x0b, 0x04, 0x3c, 0xdc, 0x6d, 0x55, 0xa0, 0x24, 0x44, 0xdd, 0x3f, + 0x34, 0x80, 0x23, 0x1c, 0x70, 0x96, 0x6c, 0xee, 0xef, 0xbf, 0xc8, 0x67, 0x7e, 0xe5, 0xaf, 0xfa, + 0x90, 0x89, 0x99, 0x5f, 0x85, 0x64, 0xe2, 0x37, 0x52, 0x9c, 0xfc, 0x8d, 0x3c, 0x00, 0x88, 0x13, + 0x1c, 0x92, 0x00, 0x71, 0x9c, 0x9e, 0xf7, 0x4c, 0x8d, 0xb1, 0x3a, 0x9f, 0x03, 0xbc, 0x16, 0x9f, + 0x2f, 0xd5, 0xe0, 0x4a, 0x33, 0x43, 0x39, 0xfc, 0xa1, 0x79, 0xe6, 0xeb, 0xe1, 0x67, 0xed, 0x26, + 0x2c, 0xc6, 0x11, 0x0a, 0x70, 0x87, 0x45, 0x21, 0x4e, 0x7c, 0x8e, 0x4e, 0x64, 0xbd, 0x9b, 0x5e, + 0x7d, 0x8c, 0x7c, 0x88, 0x4e, 0xdc, 0x3e, 0x2c, 0x48, 0x80, 0x56, 0x84, 0xe8, 0x3e, 0x0b, 0xf1, + 0x19, 0x7b, 0xb5, 0xf9, 0xed, 0xbd, 0x0c, 0x06, 0x49, 0xfd, 0x80, 0x65, 0x94, 0xe7, 0x63, 0x6d, + 0x95, 0xa4, 0xdb, 0x62, 0xeb, 0xfc, 0x0f, 0xca, 0x11, 0xe9, 0x12, 0xf5, 0x4a, 0xeb, 0x9e, 0xda, + 0xb8, 0x7f, 0x69, 0x60, 0x0c, 0xd5, 0x6e, 0x80, 0xd5, 0x93, 0xc1, 0xf6, 0x11, 0xa5, 0xe9, 0x5b, + 0xfa, 0xf9, 0x28, 0x25, 0x22, 0x6f, 0x4a, 0x66, 0x93, 0xd2, 0xd4, 0x79, 0x38, 0x61, 0xf8, 0xdb, + 0x1f, 0x25, 0x21, 0x3a, 0x66, 0xfa, 0x67, 0x50, 0x96, 0xa1, 0xcb, 0xa3, 0xbc, 0x32, 0x2b, 0xca, + 0x03, 0x6b, 0x1b, 0x05, 0x4f, 0x09, 0x88, 0xbf, 0x1c, 0xcb, 0x78, 0x9c, 0x71, 0x7f, 0x90, 0x7f, + 0x91, 0x63, 0x7d, 0x55, 0xf7, 0xea, 0x8a, 0xfe, 0x44, 0x95, 0x41, 0x2a, 0xca, 0x8a, 0xb2, 0x10, + 0xdf, 0xfa, 0x49, 0x83, 0x8a, 0xea, 0xed, 0x93, 0x13, 0xc8, 0x22, 0x58, 0x7b, 0x09, 0x46, 0x1c, + 0x27, 0x87, 0x1d, 0x44, 0x6d, 0xcd, 0xb1, 0xa1, 0x96, 0x13, 0x76, 0x5f, 0x67, 0x28, 0xb2, 0x8b, + 0x4e, 0x0d, 0x8c, 0x67, 0x38, 0x4d, 0xe5, 0xb9, 0x2e, 0x47, 0x14, 0x9c, 0xa6, 0xea, 0xb0, 0xe4, + 0x98, 0x50, 0x56, 0xcb, 0xb2, 0xe0, 0xdb, 0x67, 0x5c, 0xed, 0x2a, 0x02, 0xb8, 0x95, 0xe0, 0x63, + 0x72, 0xfa, 0x1c, 0xf1, 0xa0, 0x63, 0x57, 0x05, 0x70, 0x8b, 0xa5, 0x7c, 0x48, 0x31, 0x84, 0xac, + 0x5a, 0x9a, 0x62, 0x29, 0xfb, 0x83, 0x0d, 0x4e, 0x05, 0x8a, 0x4d, 0x6a, 0x5b, 0x82, 0xb4, 0xcf, + 0x78, 0x93, 0xda, 0xb5, 0x5b, 0x7b, 0x60, 0x8d, 0x3d, 0x89, 0xc2, 0x81, 0x97, 0xf4, 0x15, 0x65, + 0x6f, 0xa8, 0x9a, 0x03, 0x37, 0x43, 0x31, 0x3b, 0x55, 0x41, 0x7f, 0x91, 0xb5, 0xed, 0xa2, 0x58, + 0x3c, 0xcf, 0x22, 0x5b, 0x17, 0x8b, 0x1d, 0xd2, 0xb3, 0x4b, 0x92, 0xc2, 0x42, 0xbb, 0xbc, 0x75, + 0xf7, 0xeb, 0x3b, 0x27, 0x84, 0x77, 0xb2, 0xf6, 0x5a, 0xc0, 0xba, 0xeb, 0x2a, 0xdc, 0xb7, 0x09, + 0xcb, 0x57, 0xeb, 0x84, 0x72, 0x9c, 0x50, 0x14, 0xad, 0xcb, 0x0c, 0xac, 0x8b, 0x0c, 0xc4, 0xed, + 0x76, 0x45, 0xee, 0xee, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x38, 0x9d, 0xc7, 0x85, 0x59, 0x11, + 0x00, 0x00, } diff --git a/internal/proxy/task_query.go b/internal/proxy/task_query.go index 8e3ccde1384b4..472e6350e5caa 100644 --- a/internal/proxy/task_query.go +++ b/internal/proxy/task_query.go @@ -321,6 +321,7 @@ func (t *queryTask) PreExecute(ctx context.Context) error { if err := t.createPlan(ctx); err != nil { return err } + t.plan.Node.(*planpb.PlanNode_Query).Query.Limit = t.RetrieveRequest.Limit partitionNames := t.request.GetPartitionNames() if t.partitionKeyMode { diff --git a/internal/querynodev2/segments/segment.go b/internal/querynodev2/segments/segment.go index fceea87d60650..8a5f20ae87473 100644 --- a/internal/querynodev2/segments/segment.go +++ b/internal/querynodev2/segments/segment.go @@ -28,7 +28,6 @@ import "C" import ( "context" "fmt" - "sort" "sync" "unsafe" @@ -459,7 +458,8 @@ func (s *LocalSegment) Retrieve(ctx context.Context, plan *RetrievePlan) (*segco zap.Int("resultNum", len(result.Offset)), ) - sort.Sort(&byPK{result}) + // Sort was done by the segcore. + // sort.Sort(&byPK{result}) return result, nil }