diff --git a/configs/milvus.yaml b/configs/milvus.yaml index 31702a6f5f..c8d17138f5 100644 --- a/configs/milvus.yaml +++ b/configs/milvus.yaml @@ -204,9 +204,10 @@ queryNode: # This parameter is only useful when enable-disk = true. # And this value should be a number greater than 1 and less than 32. chunkRows: 1024 # The number of vectors in a chunk. - smallIndex: - nlist: 128 # small index nlist, recommend to set sqrt(chunkRows), must smaller than chunkRows/8 - nprobe: 16 # nprobe to search small index, based on your accuracy requirement, must smaller than nlist + growing: # growing a vector index for growing segment to accelerate search + enableIndex: false + nlist: 128 # growing segment index nlist + nprobe: 16 # nprobe to search growing segment, based on your accuracy requirement, must smaller than nlist loadMemoryUsageFactor: 3 # The multiply factor of calculating the memory usage while loading segments enableDisk: true # enable querynode load disk index, and search on disk index maxDiskUsagePercentage: 95 diff --git a/internal/core/src/common/CMakeLists.txt b/internal/core/src/common/CMakeLists.txt index f74e577e6d..3bff613faf 100644 --- a/internal/core/src/common/CMakeLists.txt +++ b/internal/core/src/common/CMakeLists.txt @@ -20,7 +20,7 @@ set(COMMON_SRC Common.cpp RangeSearchHelper.cpp Tracer.cpp - ) + IndexMeta.cpp) add_library(milvus_common SHARED ${COMMON_SRC}) diff --git a/internal/core/src/common/IndexMeta.cpp b/internal/core/src/common/IndexMeta.cpp new file mode 100644 index 0000000000..dff68ae777 --- /dev/null +++ b/internal/core/src/common/IndexMeta.cpp @@ -0,0 +1,95 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 "IndexMeta.h" +#include "protobuf_utils.h" +#include "log/Log.h" + +namespace milvus { + +FieldIndexMeta::FieldIndexMeta( + FieldId fieldId, + std::map&& index_params, + std::map&& type_params) { + fieldId_ = fieldId; + index_params_ = std::move(index_params); + type_params_ = std::move(type_params); +} + +FieldIndexMeta::FieldIndexMeta( + const milvus::proto::segcore::FieldIndexMeta& fieldIndexMeta) { + fieldId_ = FieldId(fieldIndexMeta.fieldid()); + index_params_ = RepeatedKeyValToMap(fieldIndexMeta.index_params()); + type_params_ = RepeatedKeyValToMap(fieldIndexMeta.type_params()); + user_index_params_ = + RepeatedKeyValToMap(fieldIndexMeta.user_index_params()); +} + +CollectionIndexMeta::CollectionIndexMeta( + int64_t max_index_row_cnt, std::map&& fieldMetas) + : max_index_row_cnt_(max_index_row_cnt), + fieldMetas_(std::move(fieldMetas)) { +} + +CollectionIndexMeta::CollectionIndexMeta( + const milvus::proto::segcore::CollectionIndexMeta& collectionIndexMeta) { + max_index_row_cnt_ = collectionIndexMeta.maxindexrowcount(); + for (auto& filed_index_meta : collectionIndexMeta.index_metas()) { + FieldIndexMeta fieldIndexMeta(filed_index_meta); + fieldMetas_.emplace(FieldId(filed_index_meta.fieldid()), + fieldIndexMeta); + } +} + +int64_t +CollectionIndexMeta::GetIndexMaxRowCount() const { + return max_index_row_cnt_; +} + +bool +CollectionIndexMeta::HasFiled(FieldId fieldId) const { + return fieldMetas_.count(fieldId); +} + +const FieldIndexMeta& +CollectionIndexMeta::GetFieldIndexMeta(FieldId fieldId) const { + assert(fieldMetas_.find(fieldId) != fieldMetas_.end()); + return fieldMetas_.at(fieldId); +} + +std::string +CollectionIndexMeta::ToString() { + std::stringstream ss; + ss << "maxRowCount : {" << max_index_row_cnt_ << "} "; + for (auto& filed_meta : fieldMetas_) { + ss << "FieldId : {" << abs(filed_meta.first.get()) << " "; + ss << "IndexParams : { "; + for (auto& kv : filed_meta.second.GetIndexParams()) { + ss << kv.first << " : " << kv.second << ", "; + } + ss << " }"; + ss << "TypeParams : {"; + for (auto& kv : filed_meta.second.GetTypeParams()) { + ss << kv.first << " : " << kv.second << ", "; + } + ss << "}"; + ss << "}"; + } + return ss.str(); +} +} // namespace milvus diff --git a/internal/core/src/common/IndexMeta.h b/internal/core/src/common/IndexMeta.h new file mode 100644 index 0000000000..89ad9fd01c --- /dev/null +++ b/internal/core/src/common/IndexMeta.h @@ -0,0 +1,92 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +#pragma once + +#include +#include + +#include "pb/common.pb.h" +#include "pb/segcore.pb.h" +#include "Types.h" + +namespace milvus { +class FieldIndexMeta { + public: + //For unittest init + FieldIndexMeta(FieldId fieldId, + std::map&& index_params, + std::map&& type_params); + + FieldIndexMeta( + const milvus::proto::segcore::FieldIndexMeta& fieldIndexMeta); + + knowhere::MetricType + GeMetricType() const { + return index_params_.at(knowhere::meta::METRIC_TYPE); + } + + knowhere::IndexType + GetIndexType() const { + return index_params_.at(knowhere::meta::INDEX_TYPE); + } + + const std::map& + GetIndexParams() const { + return index_params_; + } + + const std::map& + GetTypeParams() const { + return type_params_; + } + + private: + FieldId fieldId_; + std::map index_params_; + std::map type_params_; + std::map user_index_params_; +}; + +class CollectionIndexMeta { + public: + //just for unittest + CollectionIndexMeta(int64_t max_index_row_cnt, + std::map&& fieldMetas); + + CollectionIndexMeta( + const milvus::proto::segcore::CollectionIndexMeta& collectionIndexMeta); + + int64_t + GetIndexMaxRowCount() const; + + bool + HasFiled(FieldId fieldId) const; + + const FieldIndexMeta& + GetFieldIndexMeta(FieldId fieldId) const; + + std::string + ToString(); + + private: + int64_t max_index_row_cnt_; + std::map fieldMetas_; +}; + +using IndexMetaPtr = std::shared_ptr; + +} //namespace milvus \ No newline at end of file diff --git a/internal/core/src/common/Schema.cpp b/internal/core/src/common/Schema.cpp index 4e03af75c9..e35ff7368c 100644 --- a/internal/core/src/common/Schema.cpp +++ b/internal/core/src/common/Schema.cpp @@ -21,22 +21,11 @@ #include "Schema.h" #include "SystemProperty.h" +#include "protobuf_utils.h" namespace milvus { using std::string; -static std::map -RepeatedKeyValToMap( - const google::protobuf::RepeatedPtrField& - kvs) { - std::map mapping; - for (auto& kv : kvs) { - AssertInfo(!mapping.count(kv.key()), - "repeat key(" + kv.key() + ") in protobuf"); - mapping.emplace(kv.key(), kv.value()); - } - return mapping; -} std::shared_ptr Schema::ParseFrom(const milvus::proto::schema::CollectionSchema& schema_proto) { diff --git a/internal/core/src/common/protobuf_utils.h b/internal/core/src/common/protobuf_utils.h new file mode 100644 index 0000000000..387b168de9 --- /dev/null +++ b/internal/core/src/common/protobuf_utils.h @@ -0,0 +1,41 @@ +// Licensed to the LF AI & Data foundation under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +#pragma once + +#include +#include +#include + +#include "pb/schema.pb.h" +#include "exceptions/EasyAssert.h" + +using std::string; + +namespace milvus { +static std::map +RepeatedKeyValToMap( + const google::protobuf::RepeatedPtrField& + kvs) { + std::map mapping; + for (auto& kv : kvs) { + AssertInfo(!mapping.count(kv.key()), + "repeat key(" + kv.key() + ") in protobuf"); + mapping.emplace(kv.key(), kv.value()); + } + return mapping; +} +} //namespace milvus \ No newline at end of file diff --git a/internal/core/src/index/VectorIndex.h b/internal/core/src/index/VectorIndex.h index b92bddca93..0af21d5a17 100644 --- a/internal/core/src/index/VectorIndex.h +++ b/internal/core/src/index/VectorIndex.h @@ -46,6 +46,11 @@ class VectorIndex : public IndexBase { PanicInfo("vector index don't support build index with raw data"); }; + virtual void + AddWithDataset(const DatasetPtr& dataset, const Config& config) { + PanicInfo("vector index don't support add with dataset"); + } + virtual std::unique_ptr Query(const DatasetPtr dataset, const SearchInfo& search_info, diff --git a/internal/core/src/index/VectorMemIndex.cpp b/internal/core/src/index/VectorMemIndex.cpp index 4849c51d65..f80bb1c905 100644 --- a/internal/core/src/index/VectorMemIndex.cpp +++ b/internal/core/src/index/VectorMemIndex.cpp @@ -81,6 +81,20 @@ VectorMemIndex::BuildWithDataset(const DatasetPtr& dataset, SetDim(index_.Dim()); } +void +VectorMemIndex::AddWithDataset(const DatasetPtr& dataset, + const Config& config) { + knowhere::Json index_config; + index_config.update(config); + + knowhere::TimeRecorder rc("AddWithDataset", 1); + auto stat = index_.Add(*dataset, index_config); + if (stat != knowhere::Status::success) + PanicCodeInfo(ErrorCodeEnum::BuildIndexError, + "failed to append index, " + MatchKnowhereError(stat)); + rc.ElapseFromBegin("Done"); +} + std::unique_ptr VectorMemIndex::Query(const DatasetPtr dataset, const SearchInfo& search_info, diff --git a/internal/core/src/index/VectorMemIndex.h b/internal/core/src/index/VectorMemIndex.h index e706f34f20..9e64fb889e 100644 --- a/internal/core/src/index/VectorMemIndex.h +++ b/internal/core/src/index/VectorMemIndex.h @@ -41,6 +41,9 @@ class VectorMemIndex : public VectorIndex { BuildWithDataset(const DatasetPtr& dataset, const Config& config = {}) override; + void + AddWithDataset(const DatasetPtr& dataset, const Config& config) override; + int64_t Count() override { return index_.Count(); diff --git a/internal/core/src/index/VectorMemNMIndex.cpp b/internal/core/src/index/VectorMemNMIndex.cpp index ef136b0925..6d165cd039 100644 --- a/internal/core/src/index/VectorMemNMIndex.cpp +++ b/internal/core/src/index/VectorMemNMIndex.cpp @@ -52,6 +52,11 @@ VectorMemNMIndex::BuildWithDataset(const DatasetPtr& dataset, rc.ElapseFromBegin("Done"); } +void +VectorMemNMIndex::AddWithDataset(const DatasetPtr& /*dataset*/, + const Config& /*config*/) { +} + void VectorMemNMIndex::Load(const BinarySet& binary_set, const Config& config) { VectorMemIndex::Load(binary_set, config); diff --git a/internal/core/src/index/VectorMemNMIndex.h b/internal/core/src/index/VectorMemNMIndex.h index 49ee54e7cc..b986feedd1 100644 --- a/internal/core/src/index/VectorMemNMIndex.h +++ b/internal/core/src/index/VectorMemNMIndex.h @@ -41,6 +41,9 @@ class VectorMemNMIndex : public VectorMemIndex { BuildWithDataset(const DatasetPtr& dataset, const Config& config = {}) override; + void + AddWithDataset(const DatasetPtr& dataset, const Config& config) override; + void Load(const BinarySet& binary_set, const Config& config = {}) override; diff --git a/internal/core/src/pb/segcore.pb.cc b/internal/core/src/pb/segcore.pb.cc index 05c9238562..44ec1afcbe 100755 --- a/internal/core/src/pb/segcore.pb.cc +++ b/internal/core/src/pb/segcore.pb.cc @@ -82,10 +82,43 @@ struct InsertRecordDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 InsertRecordDefaultTypeInternal _InsertRecord_default_instance_; +PROTOBUF_CONSTEXPR FieldIndexMeta::FieldIndexMeta( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.type_params_)*/{} + , /*decltype(_impl_.index_params_)*/{} + , /*decltype(_impl_.user_index_params_)*/{} + , /*decltype(_impl_.index_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.fieldid_)*/int64_t{0} + , /*decltype(_impl_.collectionid_)*/int64_t{0} + , /*decltype(_impl_.is_auto_index_)*/false + , /*decltype(_impl_._cached_size_)*/{}} {} +struct FieldIndexMetaDefaultTypeInternal { + PROTOBUF_CONSTEXPR FieldIndexMetaDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~FieldIndexMetaDefaultTypeInternal() {} + union { + FieldIndexMeta _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldIndexMetaDefaultTypeInternal _FieldIndexMeta_default_instance_; +PROTOBUF_CONSTEXPR CollectionIndexMeta::CollectionIndexMeta( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.index_metas_)*/{} + , /*decltype(_impl_.maxindexrowcount_)*/int64_t{0} + , /*decltype(_impl_._cached_size_)*/{}} {} +struct CollectionIndexMetaDefaultTypeInternal { + PROTOBUF_CONSTEXPR CollectionIndexMetaDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~CollectionIndexMetaDefaultTypeInternal() {} + union { + CollectionIndexMeta _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CollectionIndexMetaDefaultTypeInternal _CollectionIndexMeta_default_instance_; } // namespace segcore } // namespace proto } // namespace milvus -static ::_pb::Metadata file_level_metadata_segcore_2eproto[4]; +static ::_pb::Metadata file_level_metadata_segcore_2eproto[6]; static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_segcore_2eproto = nullptr; static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_segcore_2eproto = nullptr; @@ -124,12 +157,35 @@ const uint32_t TableStruct_segcore_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE( ~0u, // no _inlined_string_donated_ PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::InsertRecord, _impl_.fields_data_), PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::InsertRecord, _impl_.num_rows_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.fieldid_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.collectionid_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.index_name_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.type_params_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.index_params_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.is_auto_index_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::FieldIndexMeta, _impl_.user_index_params_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::CollectionIndexMeta, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + ~0u, // no _inlined_string_donated_ + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::CollectionIndexMeta, _impl_.maxindexrowcount_), + PROTOBUF_FIELD_OFFSET(::milvus::proto::segcore::CollectionIndexMeta, _impl_.index_metas_), }; static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::milvus::proto::segcore::RetrieveResults)}, { 9, -1, -1, sizeof(::milvus::proto::segcore::LoadFieldMeta)}, { 18, -1, -1, sizeof(::milvus::proto::segcore::LoadSegmentMeta)}, { 26, -1, -1, sizeof(::milvus::proto::segcore::InsertRecord)}, + { 34, -1, -1, sizeof(::milvus::proto::segcore::FieldIndexMeta)}, + { 47, -1, -1, sizeof(::milvus::proto::segcore::CollectionIndexMeta)}, }; static const ::_pb::Message* const file_default_instances[] = { @@ -137,31 +193,44 @@ static const ::_pb::Message* const file_default_instances[] = { &::milvus::proto::segcore::_LoadFieldMeta_default_instance_._instance, &::milvus::proto::segcore::_LoadSegmentMeta_default_instance_._instance, &::milvus::proto::segcore::_InsertRecord_default_instance_._instance, + &::milvus::proto::segcore::_FieldIndexMeta_default_instance_._instance, + &::milvus::proto::segcore::_CollectionIndexMeta_default_instance_._instance, }; const char descriptor_table_protodef_segcore_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\rsegcore.proto\022\024milvus.proto.segcore\032\014s" - "chema.proto\"}\n\017RetrieveResults\022%\n\003ids\030\001 " - "\001(\0132\030.milvus.proto.schema.IDs\022\016\n\006offset\030" - "\002 \003(\003\0223\n\013fields_data\030\003 \003(\0132\036.milvus.prot" - "o.schema.FieldData\"P\n\rLoadFieldMeta\022\025\n\rm" - "in_timestamp\030\001 \001(\003\022\025\n\rmax_timestamp\030\002 \001(" - "\003\022\021\n\trow_count\030\003 \001(\003\"Y\n\017LoadSegmentMeta\022" - "2\n\005metas\030\001 \003(\0132#.milvus.proto.segcore.Lo" - "adFieldMeta\022\022\n\ntotal_size\030\002 \001(\003\"U\n\014Inser" - "tRecord\0223\n\013fields_data\030\001 \003(\0132\036.milvus.pr" - "oto.schema.FieldData\022\020\n\010num_rows\030\002 \001(\003B6" - "Z4github.com/milvus-io/milvus/internal/p" - "roto/segcorepbb\006proto3" + "chema.proto\032\014common.proto\"}\n\017RetrieveRes" + "ults\022%\n\003ids\030\001 \001(\0132\030.milvus.proto.schema." + "IDs\022\016\n\006offset\030\002 \003(\003\0223\n\013fields_data\030\003 \003(\013" + "2\036.milvus.proto.schema.FieldData\"P\n\rLoad" + "FieldMeta\022\025\n\rmin_timestamp\030\001 \001(\003\022\025\n\rmax_" + "timestamp\030\002 \001(\003\022\021\n\trow_count\030\003 \001(\003\"Y\n\017Lo" + "adSegmentMeta\0222\n\005metas\030\001 \003(\0132#.milvus.pr" + "oto.segcore.LoadFieldMeta\022\022\n\ntotal_size\030" + "\002 \001(\003\"U\n\014InsertRecord\0223\n\013fields_data\030\001 \003" + "(\0132\036.milvus.proto.schema.FieldData\022\020\n\010nu" + "m_rows\030\002 \001(\003\"\221\002\n\016FieldIndexMeta\022\017\n\007field" + "ID\030\001 \001(\003\022\024\n\014collectionID\030\002 \001(\003\022\022\n\nindex_" + "name\030\003 \001(\t\0226\n\013type_params\030\004 \003(\0132!.milvus" + ".proto.common.KeyValuePair\0227\n\014index_para" + "ms\030\005 \003(\0132!.milvus.proto.common.KeyValueP" + "air\022\025\n\ris_auto_index\030\006 \001(\010\022<\n\021user_index" + "_params\030\007 \003(\0132!.milvus.proto.common.KeyV" + "aluePair\"j\n\023CollectionIndexMeta\022\030\n\020maxIn" + "dexRowCount\030\001 \001(\003\0229\n\013index_metas\030\002 \003(\0132$" + ".milvus.proto.segcore.FieldIndexMetaB6Z4" + "github.com/milvus-io/milvus/internal/pro" + "to/segcorepbb\006proto3" ; -static const ::_pbi::DescriptorTable* const descriptor_table_segcore_2eproto_deps[1] = { +static const ::_pbi::DescriptorTable* const descriptor_table_segcore_2eproto_deps[2] = { + &::descriptor_table_common_2eproto, &::descriptor_table_schema_2eproto, }; static ::_pbi::once_flag descriptor_table_segcore_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_segcore_2eproto = { - false, false, 502, descriptor_table_protodef_segcore_2eproto, + false, false, 900, descriptor_table_protodef_segcore_2eproto, "segcore.proto", - &descriptor_table_segcore_2eproto_once, descriptor_table_segcore_2eproto_deps, 1, 4, + &descriptor_table_segcore_2eproto_once, descriptor_table_segcore_2eproto_deps, 2, 6, schemas, file_default_instances, TableStruct_segcore_2eproto::offsets, file_level_metadata_segcore_2eproto, file_level_enum_descriptors_segcore_2eproto, file_level_service_descriptors_segcore_2eproto, @@ -1116,6 +1185,616 @@ void InsertRecord::InternalSwap(InsertRecord* other) { file_level_metadata_segcore_2eproto[3]); } +// =================================================================== + +class FieldIndexMeta::_Internal { + public: +}; + +void FieldIndexMeta::clear_type_params() { + _impl_.type_params_.Clear(); +} +void FieldIndexMeta::clear_index_params() { + _impl_.index_params_.Clear(); +} +void FieldIndexMeta::clear_user_index_params() { + _impl_.user_index_params_.Clear(); +} +FieldIndexMeta::FieldIndexMeta(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); + // @@protoc_insertion_point(arena_constructor:milvus.proto.segcore.FieldIndexMeta) +} +FieldIndexMeta::FieldIndexMeta(const FieldIndexMeta& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + FieldIndexMeta* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.type_params_){from._impl_.type_params_} + , decltype(_impl_.index_params_){from._impl_.index_params_} + , decltype(_impl_.user_index_params_){from._impl_.user_index_params_} + , decltype(_impl_.index_name_){} + , decltype(_impl_.fieldid_){} + , decltype(_impl_.collectionid_){} + , decltype(_impl_.is_auto_index_){} + , /*decltype(_impl_._cached_size_)*/{}}; + + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _impl_.index_name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.index_name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_index_name().empty()) { + _this->_impl_.index_name_.Set(from._internal_index_name(), + _this->GetArenaForAllocation()); + } + ::memcpy(&_impl_.fieldid_, &from._impl_.fieldid_, + static_cast(reinterpret_cast(&_impl_.is_auto_index_) - + reinterpret_cast(&_impl_.fieldid_)) + sizeof(_impl_.is_auto_index_)); + // @@protoc_insertion_point(copy_constructor:milvus.proto.segcore.FieldIndexMeta) +} + +inline void FieldIndexMeta::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.type_params_){arena} + , decltype(_impl_.index_params_){arena} + , decltype(_impl_.user_index_params_){arena} + , decltype(_impl_.index_name_){} + , decltype(_impl_.fieldid_){int64_t{0}} + , decltype(_impl_.collectionid_){int64_t{0}} + , decltype(_impl_.is_auto_index_){false} + , /*decltype(_impl_._cached_size_)*/{} + }; + _impl_.index_name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.index_name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +FieldIndexMeta::~FieldIndexMeta() { + // @@protoc_insertion_point(destructor:milvus.proto.segcore.FieldIndexMeta) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void FieldIndexMeta::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + _impl_.type_params_.~RepeatedPtrField(); + _impl_.index_params_.~RepeatedPtrField(); + _impl_.user_index_params_.~RepeatedPtrField(); + _impl_.index_name_.Destroy(); +} + +void FieldIndexMeta::SetCachedSize(int size) const { + _impl_._cached_size_.Set(size); +} + +void FieldIndexMeta::Clear() { +// @@protoc_insertion_point(message_clear_start:milvus.proto.segcore.FieldIndexMeta) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _impl_.type_params_.Clear(); + _impl_.index_params_.Clear(); + _impl_.user_index_params_.Clear(); + _impl_.index_name_.ClearToEmpty(); + ::memset(&_impl_.fieldid_, 0, static_cast( + reinterpret_cast(&_impl_.is_auto_index_) - + reinterpret_cast(&_impl_.fieldid_)) + sizeof(_impl_.is_auto_index_)); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* FieldIndexMeta::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int64 fieldID = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + _impl_.fieldid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // int64 collectionID = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { + _impl_.collectionid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // string index_name = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 26)) { + auto str = _internal_mutable_index_name(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "milvus.proto.segcore.FieldIndexMeta.index_name")); + } else + goto handle_unusual; + continue; + // repeated .milvus.proto.common.KeyValuePair type_params = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_type_params(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr)); + } else + goto handle_unusual; + continue; + // repeated .milvus.proto.common.KeyValuePair index_params = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 42)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_index_params(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr)); + } else + goto handle_unusual; + continue; + // bool is_auto_index = 6; + case 6: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 48)) { + _impl_.is_auto_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .milvus.proto.common.KeyValuePair user_index_params = 7; + case 7: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 58)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_user_index_params(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<58>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* FieldIndexMeta::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:milvus.proto.segcore.FieldIndexMeta) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // int64 fieldID = 1; + if (this->_internal_fieldid() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(1, this->_internal_fieldid(), target); + } + + // int64 collectionID = 2; + if (this->_internal_collectionid() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(2, this->_internal_collectionid(), target); + } + + // string index_name = 3; + if (!this->_internal_index_name().empty()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_index_name().data(), static_cast(this->_internal_index_name().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "milvus.proto.segcore.FieldIndexMeta.index_name"); + target = stream->WriteStringMaybeAliased( + 3, this->_internal_index_name(), target); + } + + // repeated .milvus.proto.common.KeyValuePair type_params = 4; + for (unsigned i = 0, + n = static_cast(this->_internal_type_params_size()); i < n; i++) { + const auto& repfield = this->_internal_type_params(i); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream); + } + + // repeated .milvus.proto.common.KeyValuePair index_params = 5; + for (unsigned i = 0, + n = static_cast(this->_internal_index_params_size()); i < n; i++) { + const auto& repfield = this->_internal_index_params(i); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(5, repfield, repfield.GetCachedSize(), target, stream); + } + + // bool is_auto_index = 6; + if (this->_internal_is_auto_index() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(6, this->_internal_is_auto_index(), target); + } + + // repeated .milvus.proto.common.KeyValuePair user_index_params = 7; + for (unsigned i = 0, + n = static_cast(this->_internal_user_index_params_size()); i < n; i++) { + const auto& repfield = this->_internal_user_index_params(i); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(7, repfield, repfield.GetCachedSize(), target, stream); + } + + 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); + } + // @@protoc_insertion_point(serialize_to_array_end:milvus.proto.segcore.FieldIndexMeta) + return target; +} + +size_t FieldIndexMeta::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:milvus.proto.segcore.FieldIndexMeta) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .milvus.proto.common.KeyValuePair type_params = 4; + total_size += 1UL * this->_internal_type_params_size(); + for (const auto& msg : this->_impl_.type_params_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .milvus.proto.common.KeyValuePair index_params = 5; + total_size += 1UL * this->_internal_index_params_size(); + for (const auto& msg : this->_impl_.index_params_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // repeated .milvus.proto.common.KeyValuePair user_index_params = 7; + total_size += 1UL * this->_internal_user_index_params_size(); + for (const auto& msg : this->_impl_.user_index_params_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // string index_name = 3; + if (!this->_internal_index_name().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_index_name()); + } + + // int64 fieldID = 1; + if (this->_internal_fieldid() != 0) { + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_fieldid()); + } + + // int64 collectionID = 2; + if (this->_internal_collectionid() != 0) { + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_collectionid()); + } + + // bool is_auto_index = 6; + if (this->_internal_is_auto_index() != 0) { + total_size += 1 + 1; + } + + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldIndexMeta::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, + FieldIndexMeta::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldIndexMeta::GetClassData() const { return &_class_data_; } + + +void FieldIndexMeta::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:milvus.proto.segcore.FieldIndexMeta) + GOOGLE_DCHECK_NE(&from, _this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + _this->_impl_.type_params_.MergeFrom(from._impl_.type_params_); + _this->_impl_.index_params_.MergeFrom(from._impl_.index_params_); + _this->_impl_.user_index_params_.MergeFrom(from._impl_.user_index_params_); + if (!from._internal_index_name().empty()) { + _this->_internal_set_index_name(from._internal_index_name()); + } + if (from._internal_fieldid() != 0) { + _this->_internal_set_fieldid(from._internal_fieldid()); + } + if (from._internal_collectionid() != 0) { + _this->_internal_set_collectionid(from._internal_collectionid()); + } + if (from._internal_is_auto_index() != 0) { + _this->_internal_set_is_auto_index(from._internal_is_auto_index()); + } + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void FieldIndexMeta::CopyFrom(const FieldIndexMeta& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:milvus.proto.segcore.FieldIndexMeta) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldIndexMeta::IsInitialized() const { + return true; +} + +void FieldIndexMeta::InternalSwap(FieldIndexMeta* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + _impl_.type_params_.InternalSwap(&other->_impl_.type_params_); + _impl_.index_params_.InternalSwap(&other->_impl_.index_params_); + _impl_.user_index_params_.InternalSwap(&other->_impl_.user_index_params_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.index_name_, lhs_arena, + &other->_impl_.index_name_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FieldIndexMeta, _impl_.is_auto_index_) + + sizeof(FieldIndexMeta::_impl_.is_auto_index_) + - PROTOBUF_FIELD_OFFSET(FieldIndexMeta, _impl_.fieldid_)>( + reinterpret_cast(&_impl_.fieldid_), + reinterpret_cast(&other->_impl_.fieldid_)); +} + +::PROTOBUF_NAMESPACE_ID::Metadata FieldIndexMeta::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_segcore_2eproto_getter, &descriptor_table_segcore_2eproto_once, + file_level_metadata_segcore_2eproto[4]); +} + +// =================================================================== + +class CollectionIndexMeta::_Internal { + public: +}; + +CollectionIndexMeta::CollectionIndexMeta(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); + // @@protoc_insertion_point(arena_constructor:milvus.proto.segcore.CollectionIndexMeta) +} +CollectionIndexMeta::CollectionIndexMeta(const CollectionIndexMeta& from) + : ::PROTOBUF_NAMESPACE_ID::Message() { + CollectionIndexMeta* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.index_metas_){from._impl_.index_metas_} + , decltype(_impl_.maxindexrowcount_){} + , /*decltype(_impl_._cached_size_)*/{}}; + + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_impl_.maxindexrowcount_ = from._impl_.maxindexrowcount_; + // @@protoc_insertion_point(copy_constructor:milvus.proto.segcore.CollectionIndexMeta) +} + +inline void CollectionIndexMeta::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.index_metas_){arena} + , decltype(_impl_.maxindexrowcount_){int64_t{0}} + , /*decltype(_impl_._cached_size_)*/{} + }; +} + +CollectionIndexMeta::~CollectionIndexMeta() { + // @@protoc_insertion_point(destructor:milvus.proto.segcore.CollectionIndexMeta) + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void CollectionIndexMeta::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + _impl_.index_metas_.~RepeatedPtrField(); +} + +void CollectionIndexMeta::SetCachedSize(int size) const { + _impl_._cached_size_.Set(size); +} + +void CollectionIndexMeta::Clear() { +// @@protoc_insertion_point(message_clear_start:milvus.proto.segcore.CollectionIndexMeta) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _impl_.index_metas_.Clear(); + _impl_.maxindexrowcount_ = int64_t{0}; + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); +} + +const char* CollectionIndexMeta::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // int64 maxIndexRowCount = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + _impl_.maxindexrowcount_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // repeated .milvus.proto.segcore.FieldIndexMeta index_metas = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { + ptr -= 1; + do { + ptr += 1; + ptr = ctx->ParseMessage(_internal_add_index_metas(), ptr); + CHK_(ptr); + if (!ctx->DataAvailable(ptr)) break; + } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* CollectionIndexMeta::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:milvus.proto.segcore.CollectionIndexMeta) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // int64 maxIndexRowCount = 1; + if (this->_internal_maxindexrowcount() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt64ToArray(1, this->_internal_maxindexrowcount(), target); + } + + // repeated .milvus.proto.segcore.FieldIndexMeta index_metas = 2; + for (unsigned i = 0, + n = static_cast(this->_internal_index_metas_size()); i < n; i++) { + const auto& repfield = this->_internal_index_metas(i); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream); + } + + 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); + } + // @@protoc_insertion_point(serialize_to_array_end:milvus.proto.segcore.CollectionIndexMeta) + return target; +} + +size_t CollectionIndexMeta::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:milvus.proto.segcore.CollectionIndexMeta) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // repeated .milvus.proto.segcore.FieldIndexMeta index_metas = 2; + total_size += 1UL * this->_internal_index_metas_size(); + for (const auto& msg : this->_impl_.index_metas_) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); + } + + // int64 maxIndexRowCount = 1; + if (this->_internal_maxindexrowcount() != 0) { + total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_maxindexrowcount()); + } + + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); +} + +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CollectionIndexMeta::_class_data_ = { + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, + CollectionIndexMeta::MergeImpl +}; +const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CollectionIndexMeta::GetClassData() const { return &_class_data_; } + + +void CollectionIndexMeta::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:milvus.proto.segcore.CollectionIndexMeta) + GOOGLE_DCHECK_NE(&from, _this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + _this->_impl_.index_metas_.MergeFrom(from._impl_.index_metas_); + if (from._internal_maxindexrowcount() != 0) { + _this->_internal_set_maxindexrowcount(from._internal_maxindexrowcount()); + } + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); +} + +void CollectionIndexMeta::CopyFrom(const CollectionIndexMeta& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:milvus.proto.segcore.CollectionIndexMeta) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CollectionIndexMeta::IsInitialized() const { + return true; +} + +void CollectionIndexMeta::InternalSwap(CollectionIndexMeta* other) { + using std::swap; + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + _impl_.index_metas_.InternalSwap(&other->_impl_.index_metas_); + swap(_impl_.maxindexrowcount_, other->_impl_.maxindexrowcount_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata CollectionIndexMeta::GetMetadata() const { + return ::_pbi::AssignDescriptors( + &descriptor_table_segcore_2eproto_getter, &descriptor_table_segcore_2eproto_once, + file_level_metadata_segcore_2eproto[5]); +} + // @@protoc_insertion_point(namespace_scope) } // namespace segcore } // namespace proto @@ -1137,6 +1816,14 @@ template<> PROTOBUF_NOINLINE ::milvus::proto::segcore::InsertRecord* Arena::CreateMaybeMessage< ::milvus::proto::segcore::InsertRecord >(Arena* arena) { return Arena::CreateMessageInternal< ::milvus::proto::segcore::InsertRecord >(arena); } +template<> PROTOBUF_NOINLINE ::milvus::proto::segcore::FieldIndexMeta* +Arena::CreateMaybeMessage< ::milvus::proto::segcore::FieldIndexMeta >(Arena* arena) { + return Arena::CreateMessageInternal< ::milvus::proto::segcore::FieldIndexMeta >(arena); +} +template<> PROTOBUF_NOINLINE ::milvus::proto::segcore::CollectionIndexMeta* +Arena::CreateMaybeMessage< ::milvus::proto::segcore::CollectionIndexMeta >(Arena* arena) { + return Arena::CreateMessageInternal< ::milvus::proto::segcore::CollectionIndexMeta >(arena); +} PROTOBUF_NAMESPACE_CLOSE // @@protoc_insertion_point(global_scope) diff --git a/internal/core/src/pb/segcore.pb.h b/internal/core/src/pb/segcore.pb.h index 6fde0a4aad..5d45b9a217 100755 --- a/internal/core/src/pb/segcore.pb.h +++ b/internal/core/src/pb/segcore.pb.h @@ -31,6 +31,7 @@ #include // IWYU pragma: export #include #include "schema.pb.h" +#include "common.pb.h" // @@protoc_insertion_point(includes) #include #define PROTOBUF_INTERNAL_EXPORT_segcore_2eproto @@ -48,6 +49,12 @@ extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table namespace milvus { namespace proto { namespace segcore { +class CollectionIndexMeta; +struct CollectionIndexMetaDefaultTypeInternal; +extern CollectionIndexMetaDefaultTypeInternal _CollectionIndexMeta_default_instance_; +class FieldIndexMeta; +struct FieldIndexMetaDefaultTypeInternal; +extern FieldIndexMetaDefaultTypeInternal _FieldIndexMeta_default_instance_; class InsertRecord; struct InsertRecordDefaultTypeInternal; extern InsertRecordDefaultTypeInternal _InsertRecord_default_instance_; @@ -64,6 +71,8 @@ extern RetrieveResultsDefaultTypeInternal _RetrieveResults_default_instance_; } // namespace proto } // namespace milvus PROTOBUF_NAMESPACE_OPEN +template<> ::milvus::proto::segcore::CollectionIndexMeta* Arena::CreateMaybeMessage<::milvus::proto::segcore::CollectionIndexMeta>(Arena*); +template<> ::milvus::proto::segcore::FieldIndexMeta* Arena::CreateMaybeMessage<::milvus::proto::segcore::FieldIndexMeta>(Arena*); template<> ::milvus::proto::segcore::InsertRecord* Arena::CreateMaybeMessage<::milvus::proto::segcore::InsertRecord>(Arena*); template<> ::milvus::proto::segcore::LoadFieldMeta* Arena::CreateMaybeMessage<::milvus::proto::segcore::LoadFieldMeta>(Arena*); template<> ::milvus::proto::segcore::LoadSegmentMeta* Arena::CreateMaybeMessage<::milvus::proto::segcore::LoadSegmentMeta>(Arena*); @@ -781,6 +790,420 @@ class InsertRecord final : union { Impl_ _impl_; }; friend struct ::TableStruct_segcore_2eproto; }; +// ------------------------------------------------------------------- + +class FieldIndexMeta final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:milvus.proto.segcore.FieldIndexMeta) */ { + public: + inline FieldIndexMeta() : FieldIndexMeta(nullptr) {} + ~FieldIndexMeta() override; + explicit PROTOBUF_CONSTEXPR FieldIndexMeta(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + FieldIndexMeta(const FieldIndexMeta& from); + FieldIndexMeta(FieldIndexMeta&& from) noexcept + : FieldIndexMeta() { + *this = ::std::move(from); + } + + inline FieldIndexMeta& operator=(const FieldIndexMeta& from) { + CopyFrom(from); + return *this; + } + inline FieldIndexMeta& operator=(FieldIndexMeta&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const FieldIndexMeta& default_instance() { + return *internal_default_instance(); + } + static inline const FieldIndexMeta* internal_default_instance() { + return reinterpret_cast( + &_FieldIndexMeta_default_instance_); + } + static constexpr int kIndexInFileMessages = + 4; + + friend void swap(FieldIndexMeta& a, FieldIndexMeta& b) { + a.Swap(&b); + } + inline void Swap(FieldIndexMeta* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(FieldIndexMeta* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + FieldIndexMeta* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const FieldIndexMeta& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom( const FieldIndexMeta& from) { + FieldIndexMeta::MergeImpl(*this, from); + } + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(FieldIndexMeta* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "milvus.proto.segcore.FieldIndexMeta"; + } + protected: + explicit FieldIndexMeta(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kTypeParamsFieldNumber = 4, + kIndexParamsFieldNumber = 5, + kUserIndexParamsFieldNumber = 7, + kIndexNameFieldNumber = 3, + kFieldIDFieldNumber = 1, + kCollectionIDFieldNumber = 2, + kIsAutoIndexFieldNumber = 6, + }; + // repeated .milvus.proto.common.KeyValuePair type_params = 4; + int type_params_size() const; + private: + int _internal_type_params_size() const; + public: + void clear_type_params(); + ::milvus::proto::common::KeyValuePair* mutable_type_params(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* + mutable_type_params(); + private: + const ::milvus::proto::common::KeyValuePair& _internal_type_params(int index) const; + ::milvus::proto::common::KeyValuePair* _internal_add_type_params(); + public: + const ::milvus::proto::common::KeyValuePair& type_params(int index) const; + ::milvus::proto::common::KeyValuePair* add_type_params(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& + type_params() const; + + // repeated .milvus.proto.common.KeyValuePair index_params = 5; + int index_params_size() const; + private: + int _internal_index_params_size() const; + public: + void clear_index_params(); + ::milvus::proto::common::KeyValuePair* mutable_index_params(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* + mutable_index_params(); + private: + const ::milvus::proto::common::KeyValuePair& _internal_index_params(int index) const; + ::milvus::proto::common::KeyValuePair* _internal_add_index_params(); + public: + const ::milvus::proto::common::KeyValuePair& index_params(int index) const; + ::milvus::proto::common::KeyValuePair* add_index_params(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& + index_params() const; + + // repeated .milvus.proto.common.KeyValuePair user_index_params = 7; + int user_index_params_size() const; + private: + int _internal_user_index_params_size() const; + public: + void clear_user_index_params(); + ::milvus::proto::common::KeyValuePair* mutable_user_index_params(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* + mutable_user_index_params(); + private: + const ::milvus::proto::common::KeyValuePair& _internal_user_index_params(int index) const; + ::milvus::proto::common::KeyValuePair* _internal_add_user_index_params(); + public: + const ::milvus::proto::common::KeyValuePair& user_index_params(int index) const; + ::milvus::proto::common::KeyValuePair* add_user_index_params(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& + user_index_params() const; + + // string index_name = 3; + void clear_index_name(); + const std::string& index_name() const; + template + void set_index_name(ArgT0&& arg0, ArgT... args); + std::string* mutable_index_name(); + PROTOBUF_NODISCARD std::string* release_index_name(); + void set_allocated_index_name(std::string* index_name); + private: + const std::string& _internal_index_name() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_index_name(const std::string& value); + std::string* _internal_mutable_index_name(); + public: + + // int64 fieldID = 1; + void clear_fieldid(); + int64_t fieldid() const; + void set_fieldid(int64_t value); + private: + int64_t _internal_fieldid() const; + void _internal_set_fieldid(int64_t value); + public: + + // int64 collectionID = 2; + void clear_collectionid(); + int64_t collectionid() const; + void set_collectionid(int64_t value); + private: + int64_t _internal_collectionid() const; + void _internal_set_collectionid(int64_t value); + public: + + // bool is_auto_index = 6; + void clear_is_auto_index(); + bool is_auto_index() const; + void set_is_auto_index(bool value); + private: + bool _internal_is_auto_index() const; + void _internal_set_is_auto_index(bool value); + public: + + // @@protoc_insertion_point(class_scope:milvus.proto.segcore.FieldIndexMeta) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair > type_params_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair > index_params_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair > user_index_params_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr index_name_; + int64_t fieldid_; + int64_t collectionid_; + bool is_auto_index_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_segcore_2eproto; +}; +// ------------------------------------------------------------------- + +class CollectionIndexMeta final : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:milvus.proto.segcore.CollectionIndexMeta) */ { + public: + inline CollectionIndexMeta() : CollectionIndexMeta(nullptr) {} + ~CollectionIndexMeta() override; + explicit PROTOBUF_CONSTEXPR CollectionIndexMeta(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + CollectionIndexMeta(const CollectionIndexMeta& from); + CollectionIndexMeta(CollectionIndexMeta&& from) noexcept + : CollectionIndexMeta() { + *this = ::std::move(from); + } + + inline CollectionIndexMeta& operator=(const CollectionIndexMeta& from) { + CopyFrom(from); + return *this; + } + inline CollectionIndexMeta& operator=(CollectionIndexMeta&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + static const CollectionIndexMeta& default_instance() { + return *internal_default_instance(); + } + static inline const CollectionIndexMeta* internal_default_instance() { + return reinterpret_cast( + &_CollectionIndexMeta_default_instance_); + } + static constexpr int kIndexInFileMessages = + 5; + + friend void swap(CollectionIndexMeta& a, CollectionIndexMeta& b) { + a.Swap(&b); + } + inline void Swap(CollectionIndexMeta* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(CollectionIndexMeta* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + CollectionIndexMeta* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; + void CopyFrom(const CollectionIndexMeta& from); + using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; + void MergeFrom( const CollectionIndexMeta& from) { + CollectionIndexMeta::MergeImpl(*this, from); + } + private: + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); + public: + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); + void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(CollectionIndexMeta* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "milvus.proto.segcore.CollectionIndexMeta"; + } + protected: + explicit CollectionIndexMeta(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + static const ClassData _class_data_; + const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final; + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kIndexMetasFieldNumber = 2, + kMaxIndexRowCountFieldNumber = 1, + }; + // repeated .milvus.proto.segcore.FieldIndexMeta index_metas = 2; + int index_metas_size() const; + private: + int _internal_index_metas_size() const; + public: + void clear_index_metas(); + ::milvus::proto::segcore::FieldIndexMeta* mutable_index_metas(int index); + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::segcore::FieldIndexMeta >* + mutable_index_metas(); + private: + const ::milvus::proto::segcore::FieldIndexMeta& _internal_index_metas(int index) const; + ::milvus::proto::segcore::FieldIndexMeta* _internal_add_index_metas(); + public: + const ::milvus::proto::segcore::FieldIndexMeta& index_metas(int index) const; + ::milvus::proto::segcore::FieldIndexMeta* add_index_metas(); + const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::segcore::FieldIndexMeta >& + index_metas() const; + + // int64 maxIndexRowCount = 1; + void clear_maxindexrowcount(); + int64_t maxindexrowcount() const; + void set_maxindexrowcount(int64_t value); + private: + int64_t _internal_maxindexrowcount() const; + void _internal_set_maxindexrowcount(int64_t value); + public: + + // @@protoc_insertion_point(class_scope:milvus.proto.segcore.CollectionIndexMeta) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::segcore::FieldIndexMeta > index_metas_; + int64_t maxindexrowcount_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_segcore_2eproto; +}; // =================================================================== @@ -1150,6 +1573,295 @@ inline void InsertRecord::set_num_rows(int64_t value) { // @@protoc_insertion_point(field_set:milvus.proto.segcore.InsertRecord.num_rows) } +// ------------------------------------------------------------------- + +// FieldIndexMeta + +// int64 fieldID = 1; +inline void FieldIndexMeta::clear_fieldid() { + _impl_.fieldid_ = int64_t{0}; +} +inline int64_t FieldIndexMeta::_internal_fieldid() const { + return _impl_.fieldid_; +} +inline int64_t FieldIndexMeta::fieldid() const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.fieldID) + return _internal_fieldid(); +} +inline void FieldIndexMeta::_internal_set_fieldid(int64_t value) { + + _impl_.fieldid_ = value; +} +inline void FieldIndexMeta::set_fieldid(int64_t value) { + _internal_set_fieldid(value); + // @@protoc_insertion_point(field_set:milvus.proto.segcore.FieldIndexMeta.fieldID) +} + +// int64 collectionID = 2; +inline void FieldIndexMeta::clear_collectionid() { + _impl_.collectionid_ = int64_t{0}; +} +inline int64_t FieldIndexMeta::_internal_collectionid() const { + return _impl_.collectionid_; +} +inline int64_t FieldIndexMeta::collectionid() const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.collectionID) + return _internal_collectionid(); +} +inline void FieldIndexMeta::_internal_set_collectionid(int64_t value) { + + _impl_.collectionid_ = value; +} +inline void FieldIndexMeta::set_collectionid(int64_t value) { + _internal_set_collectionid(value); + // @@protoc_insertion_point(field_set:milvus.proto.segcore.FieldIndexMeta.collectionID) +} + +// string index_name = 3; +inline void FieldIndexMeta::clear_index_name() { + _impl_.index_name_.ClearToEmpty(); +} +inline const std::string& FieldIndexMeta::index_name() const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.index_name) + return _internal_index_name(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void FieldIndexMeta::set_index_name(ArgT0&& arg0, ArgT... args) { + + _impl_.index_name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:milvus.proto.segcore.FieldIndexMeta.index_name) +} +inline std::string* FieldIndexMeta::mutable_index_name() { + std::string* _s = _internal_mutable_index_name(); + // @@protoc_insertion_point(field_mutable:milvus.proto.segcore.FieldIndexMeta.index_name) + return _s; +} +inline const std::string& FieldIndexMeta::_internal_index_name() const { + return _impl_.index_name_.Get(); +} +inline void FieldIndexMeta::_internal_set_index_name(const std::string& value) { + + _impl_.index_name_.Set(value, GetArenaForAllocation()); +} +inline std::string* FieldIndexMeta::_internal_mutable_index_name() { + + return _impl_.index_name_.Mutable(GetArenaForAllocation()); +} +inline std::string* FieldIndexMeta::release_index_name() { + // @@protoc_insertion_point(field_release:milvus.proto.segcore.FieldIndexMeta.index_name) + return _impl_.index_name_.Release(); +} +inline void FieldIndexMeta::set_allocated_index_name(std::string* index_name) { + if (index_name != nullptr) { + + } else { + + } + _impl_.index_name_.SetAllocated(index_name, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.index_name_.IsDefault()) { + _impl_.index_name_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:milvus.proto.segcore.FieldIndexMeta.index_name) +} + +// repeated .milvus.proto.common.KeyValuePair type_params = 4; +inline int FieldIndexMeta::_internal_type_params_size() const { + return _impl_.type_params_.size(); +} +inline int FieldIndexMeta::type_params_size() const { + return _internal_type_params_size(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::mutable_type_params(int index) { + // @@protoc_insertion_point(field_mutable:milvus.proto.segcore.FieldIndexMeta.type_params) + return _impl_.type_params_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* +FieldIndexMeta::mutable_type_params() { + // @@protoc_insertion_point(field_mutable_list:milvus.proto.segcore.FieldIndexMeta.type_params) + return &_impl_.type_params_; +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::_internal_type_params(int index) const { + return _impl_.type_params_.Get(index); +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::type_params(int index) const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.type_params) + return _internal_type_params(index); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::_internal_add_type_params() { + return _impl_.type_params_.Add(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::add_type_params() { + ::milvus::proto::common::KeyValuePair* _add = _internal_add_type_params(); + // @@protoc_insertion_point(field_add:milvus.proto.segcore.FieldIndexMeta.type_params) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& +FieldIndexMeta::type_params() const { + // @@protoc_insertion_point(field_list:milvus.proto.segcore.FieldIndexMeta.type_params) + return _impl_.type_params_; +} + +// repeated .milvus.proto.common.KeyValuePair index_params = 5; +inline int FieldIndexMeta::_internal_index_params_size() const { + return _impl_.index_params_.size(); +} +inline int FieldIndexMeta::index_params_size() const { + return _internal_index_params_size(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::mutable_index_params(int index) { + // @@protoc_insertion_point(field_mutable:milvus.proto.segcore.FieldIndexMeta.index_params) + return _impl_.index_params_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* +FieldIndexMeta::mutable_index_params() { + // @@protoc_insertion_point(field_mutable_list:milvus.proto.segcore.FieldIndexMeta.index_params) + return &_impl_.index_params_; +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::_internal_index_params(int index) const { + return _impl_.index_params_.Get(index); +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::index_params(int index) const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.index_params) + return _internal_index_params(index); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::_internal_add_index_params() { + return _impl_.index_params_.Add(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::add_index_params() { + ::milvus::proto::common::KeyValuePair* _add = _internal_add_index_params(); + // @@protoc_insertion_point(field_add:milvus.proto.segcore.FieldIndexMeta.index_params) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& +FieldIndexMeta::index_params() const { + // @@protoc_insertion_point(field_list:milvus.proto.segcore.FieldIndexMeta.index_params) + return _impl_.index_params_; +} + +// bool is_auto_index = 6; +inline void FieldIndexMeta::clear_is_auto_index() { + _impl_.is_auto_index_ = false; +} +inline bool FieldIndexMeta::_internal_is_auto_index() const { + return _impl_.is_auto_index_; +} +inline bool FieldIndexMeta::is_auto_index() const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.is_auto_index) + return _internal_is_auto_index(); +} +inline void FieldIndexMeta::_internal_set_is_auto_index(bool value) { + + _impl_.is_auto_index_ = value; +} +inline void FieldIndexMeta::set_is_auto_index(bool value) { + _internal_set_is_auto_index(value); + // @@protoc_insertion_point(field_set:milvus.proto.segcore.FieldIndexMeta.is_auto_index) +} + +// repeated .milvus.proto.common.KeyValuePair user_index_params = 7; +inline int FieldIndexMeta::_internal_user_index_params_size() const { + return _impl_.user_index_params_.size(); +} +inline int FieldIndexMeta::user_index_params_size() const { + return _internal_user_index_params_size(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::mutable_user_index_params(int index) { + // @@protoc_insertion_point(field_mutable:milvus.proto.segcore.FieldIndexMeta.user_index_params) + return _impl_.user_index_params_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >* +FieldIndexMeta::mutable_user_index_params() { + // @@protoc_insertion_point(field_mutable_list:milvus.proto.segcore.FieldIndexMeta.user_index_params) + return &_impl_.user_index_params_; +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::_internal_user_index_params(int index) const { + return _impl_.user_index_params_.Get(index); +} +inline const ::milvus::proto::common::KeyValuePair& FieldIndexMeta::user_index_params(int index) const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.FieldIndexMeta.user_index_params) + return _internal_user_index_params(index); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::_internal_add_user_index_params() { + return _impl_.user_index_params_.Add(); +} +inline ::milvus::proto::common::KeyValuePair* FieldIndexMeta::add_user_index_params() { + ::milvus::proto::common::KeyValuePair* _add = _internal_add_user_index_params(); + // @@protoc_insertion_point(field_add:milvus.proto.segcore.FieldIndexMeta.user_index_params) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::common::KeyValuePair >& +FieldIndexMeta::user_index_params() const { + // @@protoc_insertion_point(field_list:milvus.proto.segcore.FieldIndexMeta.user_index_params) + return _impl_.user_index_params_; +} + +// ------------------------------------------------------------------- + +// CollectionIndexMeta + +// int64 maxIndexRowCount = 1; +inline void CollectionIndexMeta::clear_maxindexrowcount() { + _impl_.maxindexrowcount_ = int64_t{0}; +} +inline int64_t CollectionIndexMeta::_internal_maxindexrowcount() const { + return _impl_.maxindexrowcount_; +} +inline int64_t CollectionIndexMeta::maxindexrowcount() const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.CollectionIndexMeta.maxIndexRowCount) + return _internal_maxindexrowcount(); +} +inline void CollectionIndexMeta::_internal_set_maxindexrowcount(int64_t value) { + + _impl_.maxindexrowcount_ = value; +} +inline void CollectionIndexMeta::set_maxindexrowcount(int64_t value) { + _internal_set_maxindexrowcount(value); + // @@protoc_insertion_point(field_set:milvus.proto.segcore.CollectionIndexMeta.maxIndexRowCount) +} + +// repeated .milvus.proto.segcore.FieldIndexMeta index_metas = 2; +inline int CollectionIndexMeta::_internal_index_metas_size() const { + return _impl_.index_metas_.size(); +} +inline int CollectionIndexMeta::index_metas_size() const { + return _internal_index_metas_size(); +} +inline void CollectionIndexMeta::clear_index_metas() { + _impl_.index_metas_.Clear(); +} +inline ::milvus::proto::segcore::FieldIndexMeta* CollectionIndexMeta::mutable_index_metas(int index) { + // @@protoc_insertion_point(field_mutable:milvus.proto.segcore.CollectionIndexMeta.index_metas) + return _impl_.index_metas_.Mutable(index); +} +inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::segcore::FieldIndexMeta >* +CollectionIndexMeta::mutable_index_metas() { + // @@protoc_insertion_point(field_mutable_list:milvus.proto.segcore.CollectionIndexMeta.index_metas) + return &_impl_.index_metas_; +} +inline const ::milvus::proto::segcore::FieldIndexMeta& CollectionIndexMeta::_internal_index_metas(int index) const { + return _impl_.index_metas_.Get(index); +} +inline const ::milvus::proto::segcore::FieldIndexMeta& CollectionIndexMeta::index_metas(int index) const { + // @@protoc_insertion_point(field_get:milvus.proto.segcore.CollectionIndexMeta.index_metas) + return _internal_index_metas(index); +} +inline ::milvus::proto::segcore::FieldIndexMeta* CollectionIndexMeta::_internal_add_index_metas() { + return _impl_.index_metas_.Add(); +} +inline ::milvus::proto::segcore::FieldIndexMeta* CollectionIndexMeta::add_index_metas() { + ::milvus::proto::segcore::FieldIndexMeta* _add = _internal_add_index_metas(); + // @@protoc_insertion_point(field_add:milvus.proto.segcore.CollectionIndexMeta.index_metas) + return _add; +} +inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::milvus::proto::segcore::FieldIndexMeta >& +CollectionIndexMeta::index_metas() const { + // @@protoc_insertion_point(field_list:milvus.proto.segcore.CollectionIndexMeta.index_metas) + return _impl_.index_metas_; +} + #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // __GNUC__ @@ -1159,6 +1871,10 @@ inline void InsertRecord::set_num_rows(int64_t value) { // ------------------------------------------------------------------- +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) diff --git a/internal/core/src/query/SearchOnGrowing.cpp b/internal/core/src/query/SearchOnGrowing.cpp index a60f8b0ac1..8782890fa5 100644 --- a/internal/core/src/query/SearchOnGrowing.cpp +++ b/internal/core/src/query/SearchOnGrowing.cpp @@ -18,18 +18,14 @@ namespace milvus::query { -// TODO: small index is disabled, however 3 unittests still call this API, consider to remove this API -// - Query::ExecWithPredicateLoader -// - Query::ExecWithPredicate -// - Query::ExecWithoutPredicate -int32_t -FloatIndexSearch(const segcore::SegmentGrowingImpl& segment, - const SearchInfo& info, - const void* query_data, - int64_t num_queries, - int64_t ins_barrier, - const BitsetView& bitset, - SubSearchResult& results) { +void +FloatSegmentIndexSearch(const segcore::SegmentGrowingImpl& segment, + const SearchInfo& info, + const void* query_data, + int64_t num_queries, + int64_t ins_barrier, + const BitsetView& bitset, + SubSearchResult& results) { auto& schema = segment.get_schema(); auto& indexing_record = segment.get_indexing_record(); auto& record = segment.get_insert_record(); @@ -45,47 +41,17 @@ FloatIndexSearch(const segcore::SegmentGrowingImpl& segment, info.round_decimal_, field.get_dim(), query_data}; - auto vec_ptr = record.get_field_data(vecfield_id); - - int current_chunk_id = 0; if (indexing_record.is_in(vecfield_id)) { - auto max_indexed_id = indexing_record.get_finished_ack(); const auto& field_indexing = indexing_record.get_vec_field_indexing(vecfield_id); - auto search_params = field_indexing.get_search_params(info.topk_); - SearchInfo search_conf(info); - search_conf.search_params_ = search_params; - AssertInfo(vec_ptr->get_size_per_chunk() == - field_indexing.get_size_per_chunk(), - "[FloatSearch]Chunk size of vector not equal to chunk size " - "of field index"); - auto size_per_chunk = field_indexing.get_size_per_chunk(); - for (int chunk_id = current_chunk_id; chunk_id < max_indexed_id; - ++chunk_id) { - if ((chunk_id + 1) * size_per_chunk > ins_barrier) { - break; - } - - auto indexing = field_indexing.get_chunk_indexing(chunk_id); - auto sub_view = - bitset.subview(chunk_id * size_per_chunk, size_per_chunk); - auto vec_index = (index::VectorIndex*)(indexing); - auto sub_qr = SearchOnIndex( - search_dataset, *vec_index, search_conf, sub_view); - - // convert chunk uid to segment uid - for (auto& x : sub_qr.mutable_seg_offsets()) { - if (x != -1) { - x += chunk_id * size_per_chunk; - } - } - - results.merge(sub_qr); - current_chunk_id++; - } + auto indexing = field_indexing.get_segment_indexing(); + SearchInfo search_conf = field_indexing.get_search_params(info); + auto vec_index = dynamic_cast(indexing); + auto result = + SearchOnIndex(search_dataset, *vec_index, search_conf, bitset); + results.merge(result); } - return current_chunk_id; } void @@ -121,49 +87,54 @@ SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, dataset::SearchDataset search_dataset{ metric_type, num_queries, topk, round_decimal, dim, query_data}; - int32_t current_chunk_id = 0; - if (field.get_data_type() == DataType::VECTOR_FLOAT) { - current_chunk_id = FloatIndexSearch(segment, - info, - query_data, - num_queries, - active_count, - bitset, - final_qr); - } + if (segment.get_indexing_record().SyncDataWithIndex(field.get_id())) { + FloatSegmentIndexSearch(segment, + info, + query_data, + num_queries, + active_count, + bitset, + final_qr); + results.distances_ = std::move(final_qr.mutable_distances()); + results.seg_offsets_ = std::move(final_qr.mutable_seg_offsets()); + results.unity_topK_ = topk; + results.total_nq_ = num_queries; + } else { + int32_t current_chunk_id = 0; + // step 3: brute force search where small indexing is unavailable + auto vec_ptr = record.get_field_data_base(vecfield_id); + auto vec_size_per_chunk = vec_ptr->get_size_per_chunk(); + auto max_chunk = upper_div(active_count, vec_size_per_chunk); - // step 3: brute force search where small indexing is unavailable - auto vec_ptr = record.get_field_data_base(vecfield_id); - auto vec_size_per_chunk = vec_ptr->get_size_per_chunk(); - auto max_chunk = upper_div(active_count, vec_size_per_chunk); + for (int chunk_id = current_chunk_id; chunk_id < max_chunk; + ++chunk_id) { + auto chunk_data = vec_ptr->get_chunk_data(chunk_id); - for (int chunk_id = current_chunk_id; chunk_id < max_chunk; ++chunk_id) { - auto chunk_data = vec_ptr->get_chunk_data(chunk_id); + auto element_begin = chunk_id * vec_size_per_chunk; + auto element_end = + std::min(active_count, (chunk_id + 1) * vec_size_per_chunk); + auto size_per_chunk = element_end - element_begin; - auto element_begin = chunk_id * vec_size_per_chunk; - auto element_end = - std::min(active_count, (chunk_id + 1) * vec_size_per_chunk); - auto size_per_chunk = element_end - element_begin; + auto sub_view = bitset.subview(element_begin, size_per_chunk); + auto sub_qr = BruteForceSearch(search_dataset, + chunk_data, + size_per_chunk, + info.search_params_, + sub_view); - auto sub_view = bitset.subview(element_begin, size_per_chunk); - auto sub_qr = BruteForceSearch(search_dataset, - chunk_data, - size_per_chunk, - info.search_params_, - sub_view); - - // convert chunk uid to segment uid - for (auto& x : sub_qr.mutable_seg_offsets()) { - if (x != -1) { - x += chunk_id * vec_size_per_chunk; + // convert chunk uid to segment uid + for (auto& x : sub_qr.mutable_seg_offsets()) { + if (x != -1) { + x += chunk_id * vec_size_per_chunk; + } } + final_qr.merge(sub_qr); } - final_qr.merge(sub_qr); + results.distances_ = std::move(final_qr.mutable_distances()); + results.seg_offsets_ = std::move(final_qr.mutable_seg_offsets()); + results.unity_topK_ = topk; + results.total_nq_ = num_queries; } - results.distances_ = std::move(final_qr.mutable_distances()); - results.seg_offsets_ = std::move(final_qr.mutable_seg_offsets()); - results.unity_topK_ = topk; - results.total_nq_ = num_queries; } } // namespace milvus::query diff --git a/internal/core/src/segcore/CMakeLists.txt b/internal/core/src/segcore/CMakeLists.txt index 962a86ccc6..d32773f58a 100644 --- a/internal/core/src/segcore/CMakeLists.txt +++ b/internal/core/src/segcore/CMakeLists.txt @@ -32,6 +32,7 @@ set(SEGCORE_FILES load_index_c.cpp SegmentInterface.cpp SegcoreConfig.cpp + IndexConfigGenerator.cpp segcore_init_c.cpp ScalarIndex.cpp TimestampIndex.cpp diff --git a/internal/core/src/segcore/Collection.cpp b/internal/core/src/segcore/Collection.cpp index 52cb7614dd..dfbca013aa 100644 --- a/internal/core/src/segcore/Collection.cpp +++ b/internal/core/src/segcore/Collection.cpp @@ -13,6 +13,7 @@ #include "pb/schema.pb.h" #include "segcore/Collection.h" +#include "log/Log.h" namespace milvus::segcore { @@ -47,4 +48,22 @@ Collection::parse() { schema_ = Schema::ParseFrom(collection_schema); } +void +Collection::parseIndexMeta(const std::string_view index_meta_proto_) { + Assert(!index_meta_proto_.empty()); + + milvus::proto::segcore::CollectionIndexMeta protobuf_indexMeta; + auto suc = google::protobuf::TextFormat::ParseFromString( + std::string(index_meta_proto_), &protobuf_indexMeta); + + if (!suc) { + LOG_SEGCORE_ERROR_ << "unmarshal index meta string failed" << std::endl; + return; + } + + index_meta_ = std::shared_ptr( + new CollectionIndexMeta(protobuf_indexMeta)); + LOG_SEGCORE_INFO_ << "index meta info : " << index_meta_->ToString(); +} + } // namespace milvus::segcore diff --git a/internal/core/src/segcore/Collection.h b/internal/core/src/segcore/Collection.h index 414922536e..46e417b839 100644 --- a/internal/core/src/segcore/Collection.h +++ b/internal/core/src/segcore/Collection.h @@ -15,6 +15,7 @@ #include #include "common/Schema.h" +#include "common/IndexMeta.h" namespace milvus::segcore { @@ -25,12 +26,20 @@ class Collection { void parse(); + void + parseIndexMeta(const std::string_view index_meta_proto_blob); + public: SchemaPtr& get_schema() { return schema_; } + IndexMetaPtr& + GetIndexMeta() { + return index_meta_; + } + const std::string_view get_collection_name() { return collection_name_; @@ -40,6 +49,7 @@ class Collection { std::string collection_name_; std::string schema_proto_; SchemaPtr schema_; + IndexMetaPtr index_meta_; }; using CollectionPtr = std::unique_ptr; diff --git a/internal/core/src/segcore/FieldIndexing.cpp b/internal/core/src/segcore/FieldIndexing.cpp index 0c05337e01..25b7edfee1 100644 --- a/internal/core/src/segcore/FieldIndexing.cpp +++ b/internal/core/src/segcore/FieldIndexing.cpp @@ -17,9 +17,20 @@ #include "common/SystemProperty.h" #include "segcore/FieldIndexing.h" #include "index/VectorMemNMIndex.h" +#include "IndexConfigGenerator.h" namespace milvus::segcore { +VectorFieldIndexing::VectorFieldIndexing(const FieldMeta& field_meta, + const FieldIndexMeta& field_index_meta, + int64_t segment_max_row_count, + const SegcoreConfig& segcore_config) + : FieldIndexing(field_meta, segcore_config), + config_(std::make_unique( + segment_max_row_count, field_index_meta, segcore_config)), + sync_with_index(false) { +} + void VectorFieldIndexing::BuildIndexRange(int64_t ack_beg, int64_t ack_end, @@ -45,39 +56,136 @@ VectorFieldIndexing::BuildIndexRange(int64_t ack_beg, } } -knowhere::Json -VectorFieldIndexing::get_build_params() const { - // TODO - auto type_opt = field_meta_.get_metric_type(); - AssertInfo(type_opt.has_value(), - "Metric type of field meta doesn't have value"); - auto& metric_type = type_opt.value(); - auto& config = segcore_config_.at(metric_type); - auto base_params = config.build_params; +void +VectorFieldIndexing::GetDataFromIndex(const int64_t* seg_offsets, + int64_t count, + int64_t element_size, + void* output) { + auto ids_ds = std::make_shared(); + ids_ds->SetRows(count); + ids_ds->SetDim(1); + ids_ds->SetIds(seg_offsets); + ids_ds->SetIsOwner(false); - AssertInfo(base_params.count("nlist"), "Can't get nlist from index params"); - base_params[knowhere::meta::DIM] = std::to_string(field_meta_.get_dim()); - base_params[knowhere::meta::METRIC_TYPE] = metric_type; + auto& vector = index_->GetVector(ids_ds); - return base_params; + std::memcpy(output, vector.data(), count * element_size); +} + +void +VectorFieldIndexing::AppendSegmentIndex(int64_t reserved_offset, + int64_t size, + const VectorBase* vec_base, + const void* data_source) { + AssertInfo(field_meta_.get_data_type() == DataType::VECTOR_FLOAT, + "Data type of vector field is not VECTOR_FLOAT"); + + auto dim = field_meta_.get_dim(); + auto conf = get_build_params(); + auto source = dynamic_cast*>(vec_base); + + auto per_chunk = source->get_size_per_chunk(); + //append vector [vector_id_beg, vector_id_end] into index + //build index [vector_id_beg, build_threshold) when index not exist + if (!index_.get()) { + idx_t vector_id_beg = index_cur_.load(); + idx_t vector_id_end = get_build_threshold() - 1; + auto chunk_id_beg = vector_id_beg / per_chunk; + auto chunk_id_end = vector_id_end / per_chunk; + + int64_t vec_num = vector_id_end - vector_id_beg + 1; + // for train index + const void* data_addr; + std::unique_ptr vec_data; + //all train data in one chunk + if (chunk_id_beg == chunk_id_end) { + data_addr = vec_base->get_chunk_data(chunk_id_beg); + } else { + //merge data from multiple chunks together + vec_data = std::make_unique(vec_num * dim); + int64_t offset = 0; + //copy vector data [vector_id_beg, vector_id_end] + for (int chunk_id = chunk_id_beg; chunk_id <= chunk_id_end; + chunk_id++) { + int chunk_offset = 0; + int chunk_copysz = + chunk_id == chunk_id_end + ? vector_id_end - chunk_id * per_chunk + 1 + : per_chunk; + std::memcpy(vec_data.get() + offset * dim, + (const float*)vec_base->get_chunk_data(chunk_id) + + chunk_offset * dim, + chunk_copysz * dim * sizeof(float)); + offset += chunk_copysz; + } + data_addr = vec_data.get(); + } + auto dataset = knowhere::GenDataSet(vec_num, dim, data_addr); + dataset->SetIsOwner(false); + auto indexing = std::make_unique( + config_->GetIndexType(), config_->GetMetricType()); + indexing->BuildWithDataset(dataset, conf); + index_cur_.fetch_add(vec_num); + index_ = std::move(indexing); + } + //append rest data when index exist + idx_t vector_id_beg = index_cur_.load(); + idx_t vector_id_end = reserved_offset + size - 1; + auto chunk_id_beg = vector_id_beg / per_chunk; + auto chunk_id_end = vector_id_end / per_chunk; + int64_t vec_num = vector_id_end - vector_id_beg + 1; + + if (vec_num <= 0) { + sync_with_index.store(true); + return; + } + + if (sync_with_index.load()) { + auto dataset = knowhere::GenDataSet(vec_num, dim, data_source); + index_->AddWithDataset(dataset, conf); + index_cur_.fetch_add(vec_num); + } else { + for (int chunk_id = chunk_id_beg; chunk_id <= chunk_id_end; + chunk_id++) { + int chunk_offset = chunk_id == chunk_id_beg + ? index_cur_ - chunk_id * per_chunk + : 0; + int chunk_sz = chunk_id == chunk_id_end + ? vector_id_end % per_chunk - chunk_offset + 1 + : per_chunk - chunk_offset; + auto dataset = knowhere::GenDataSet( + chunk_sz, + dim, + (const float*)source->get_chunk_data(chunk_id) + + chunk_offset * dim); + index_->AddWithDataset(dataset, conf); + index_cur_.fetch_add(chunk_sz); + } + sync_with_index.store(true); + } } knowhere::Json -VectorFieldIndexing::get_search_params(int top_K) const { - // TODO - auto type_opt = field_meta_.get_metric_type(); - AssertInfo(type_opt.has_value(), - "Metric type of field meta doesn't have value"); - auto& metric_type = type_opt.value(); - auto& config = segcore_config_.at(metric_type); +VectorFieldIndexing::get_build_params() const { + auto config = config_->GetBuildBaseParams(); + config[knowhere::meta::DIM] = std::to_string(field_meta_.get_dim()); + config[knowhere::meta::NUM_BUILD_THREAD] = std::to_string(1); + return config; +} - auto base_params = config.search_params; - AssertInfo(base_params.count("nprobe"), - "Can't get nprobe from base params"); - base_params[knowhere::meta::TOPK] = top_K; - base_params[knowhere::meta::METRIC_TYPE] = metric_type; +SearchInfo +VectorFieldIndexing::get_search_params(const SearchInfo& searchInfo) const { + auto conf = config_->GetSearchConf(searchInfo); + return conf; +} - return base_params; +idx_t +VectorFieldIndexing::get_index_cursor() { + return index_cur_.load(); +} +bool +VectorFieldIndexing::sync_data_with_index() const { + return sync_with_index.load(); } template @@ -107,10 +215,15 @@ ScalarFieldIndexing::BuildIndexRange(int64_t ack_beg, } std::unique_ptr -CreateIndex(const FieldMeta& field_meta, const SegcoreConfig& segcore_config) { +CreateIndex(const FieldMeta& field_meta, + const FieldIndexMeta& field_index_meta, + int64_t segment_max_row_count, + const SegcoreConfig& segcore_config) { if (field_meta.is_vector()) { if (field_meta.get_data_type() == DataType::VECTOR_FLOAT) { return std::make_unique(field_meta, + field_index_meta, + segment_max_row_count, segcore_config); } else { // TODO diff --git a/internal/core/src/segcore/FieldIndexing.h b/internal/core/src/segcore/FieldIndexing.h index 83de44d566..b31350f4f6 100644 --- a/internal/core/src/segcore/FieldIndexing.h +++ b/internal/core/src/segcore/FieldIndexing.h @@ -22,6 +22,8 @@ #include "AckResponder.h" #include "InsertRecord.h" #include "common/Schema.h" +#include "common/IndexMeta.h" +#include "IndexConfigGenerator.h" #include "segcore/SegcoreConfig.h" #include "index/VectorIndex.h" @@ -46,11 +48,32 @@ class FieldIndexing { int64_t ack_end, const VectorBase* vec_base) = 0; + virtual void + AppendSegmentIndex(int64_t reserved_offset, + int64_t size, + const VectorBase* vec_base, + const void* data_source) = 0; + + virtual void + GetDataFromIndex(const int64_t* seg_offsets, + int64_t count, + int64_t element_size, + void* output) = 0; + + virtual int64_t + get_build_threshold() const = 0; + + virtual bool + sync_data_with_index() const = 0; + const FieldMeta& get_field_meta() { return field_meta_; } + virtual idx_t + get_index_cursor() = 0; + int64_t get_size_per_chunk() const { return segcore_config_.get_chunk_rows(); @@ -59,6 +82,9 @@ class FieldIndexing { virtual index::IndexBase* get_chunk_indexing(int64_t chunk_id) const = 0; + virtual index::IndexBase* + get_segment_indexing() const = 0; + protected: // additional info const FieldMeta& field_meta_; @@ -75,6 +101,36 @@ class ScalarFieldIndexing : public FieldIndexing { int64_t ack_end, const VectorBase* vec_base) override; + void + AppendSegmentIndex(int64_t reserved_offset, + int64_t size, + const VectorBase* vec_base, + const void* data_source) override { + PanicInfo("scalar index don't support append segment index"); + } + + void + GetDataFromIndex(const int64_t* seg_offsets, + int64_t count, + int64_t element_size, + void* output) override { + PanicInfo("scalar index don't support get data from index"); + } + idx_t + get_index_cursor() override { + return 0; + } + + int64_t + get_build_threshold() const override { + return 0; + } + + bool + sync_data_with_index() const override { + return false; + } + // concurrent index::ScalarIndex* get_chunk_indexing(int64_t chunk_id) const override { @@ -82,6 +138,11 @@ class ScalarFieldIndexing : public FieldIndexing { return data_.at(chunk_id).get(); } + index::IndexBase* + get_segment_indexing() const override { + return nullptr; + } + private: tbb::concurrent_vector> data_; }; @@ -90,36 +151,78 @@ class VectorFieldIndexing : public FieldIndexing { public: using FieldIndexing::FieldIndexing; + explicit VectorFieldIndexing(const FieldMeta& field_meta, + const FieldIndexMeta& field_index_meta, + int64_t segment_max_row_count, + const SegcoreConfig& segcore_config); + void BuildIndexRange(int64_t ack_beg, int64_t ack_end, const VectorBase* vec_base) override; + void + AppendSegmentIndex(int64_t reserved_offset, + int64_t size, + const VectorBase* vec_base, + const void* data_source) override; + + void + GetDataFromIndex(const int64_t* seg_offsets, + int64_t count, + int64_t element_size, + void* output) override; + + int64_t + get_build_threshold() const override { + return config_->GetBuildThreshold(); + } + // concurrent index::IndexBase* get_chunk_indexing(int64_t chunk_id) const override { Assert(field_meta_.is_vector()); return data_.at(chunk_id).get(); } + index::IndexBase* + get_segment_indexing() const override { + return index_.get(); + } + + bool + sync_data_with_index() const override; + + idx_t + get_index_cursor() override; knowhere::Json get_build_params() const; - knowhere::Json - get_search_params(int top_k) const; + SearchInfo + get_search_params(const SearchInfo& searchInfo) const; private: + std::atomic index_cur_ = 0; + std::atomic sync_with_index; + std::unique_ptr config_; + std::unique_ptr index_; tbb::concurrent_vector> data_; }; std::unique_ptr -CreateIndex(const FieldMeta& field_meta, const SegcoreConfig& segcore_config); +CreateIndex(const FieldMeta& field_meta, + const FieldIndexMeta& field_index_meta, + int64_t segment_max_row_count, + const SegcoreConfig& segcore_config); class IndexingRecord { public: explicit IndexingRecord(const Schema& schema, + const IndexMetaPtr& indexMetaPtr, const SegcoreConfig& segcore_config) - : schema_(schema), segcore_config_(segcore_config) { + : schema_(schema), + index_meta_(indexMetaPtr), + segcore_config_(segcore_config) { Initialize(); } @@ -128,25 +231,23 @@ class IndexingRecord { int offset_id = 0; for (auto& [field_id, field_meta] : schema_.get_fields()) { ++offset_id; - - if (field_meta.is_vector()) { + if (field_meta.is_vector() && + segcore_config_.get_enable_growing_segment_index()) { // TODO: skip binary small index now, reenable after config.yaml is ready if (field_meta.get_data_type() == DataType::VECTOR_BINARY) { continue; } - // flat should be skipped - if (!field_meta.get_metric_type().has_value()) { - continue; + //Small-Index disabled, create index for vector filed only + if (index_meta_->GetIndexMaxRowCount() > 0 && + index_meta_->HasFiled(field_id)) { + field_indexings_.try_emplace( + field_id, + CreateIndex(field_meta, + index_meta_->GetFieldIndexMeta(field_id), + index_meta_->GetIndexMaxRowCount(), + segcore_config_)); } } - if (field_meta.get_data_type() == DataType::ARRAY || - field_meta.get_data_type() == DataType::JSON) { - // not supported yet - continue; - } - - field_indexings_.try_emplace( - field_id, CreateIndex(field_meta, segcore_config_)); } assert(offset_id == schema_.size()); } @@ -154,29 +255,53 @@ class IndexingRecord { // concurrent, reentrant template void - UpdateResourceAck(int64_t chunk_ack, - const InsertRecord& record) { - if (resource_ack_ >= chunk_ack) { - return; + AppendingIndex(int64_t reserved_offset, + int64_t size, + FieldId fieldId, + const DataArray* stream_data, + const InsertRecord& record) { + if (is_in(fieldId)) { + auto& indexing = field_indexings_.at(fieldId); + if (indexing->get_field_meta().is_vector() && + indexing->get_field_meta().get_data_type() == + DataType::VECTOR_FLOAT && + reserved_offset + size >= indexing->get_build_threshold()) { + auto vec_base = record.get_field_data_base(fieldId); + indexing->AppendSegmentIndex( + reserved_offset, + size, + vec_base, + stream_data->vectors().float_vector().data().data()); + } } - - std::unique_lock lck(mutex_); - int64_t old_ack = resource_ack_; - if (old_ack >= chunk_ack) { - return; - } - resource_ack_ = chunk_ack; - lck.unlock(); - - // std::thread([this, old_ack, chunk_ack, &record] { - for (auto& [field_offset, entry] : field_indexings_) { - auto vec_base = record.get_field_data_base(field_offset); - entry->BuildIndexRange(old_ack, chunk_ack, vec_base); - } - finished_ack_.AddSegment(old_ack, chunk_ack); - // }).detach(); } + void + GetDataFromIndex(FieldId fieldId, + const int64_t* seg_offsets, + int64_t count, + int64_t element_size, + void* output_raw) const { + if (is_in(fieldId)) { + auto& indexing = field_indexings_.at(fieldId); + if (indexing->get_field_meta().is_vector() && + indexing->get_field_meta().get_data_type() == + DataType::VECTOR_FLOAT) { + indexing->GetDataFromIndex( + seg_offsets, count, element_size, output_raw); + } + } + } + + // result shows the index has synchronized with all inserted data or not + bool + SyncDataWithIndex(FieldId fieldId) const { + if (is_in(fieldId)) { + const FieldIndexing& indexing = get_field_indexing(fieldId); + return indexing.sync_data_with_index(); + } + return false; + } // concurrent int64_t get_finished_ack() const { @@ -214,6 +339,7 @@ class IndexingRecord { private: const Schema& schema_; + IndexMetaPtr index_meta_; const SegcoreConfig& segcore_config_; private: diff --git a/internal/core/src/segcore/IndexConfigGenerator.cpp b/internal/core/src/segcore/IndexConfigGenerator.cpp new file mode 100644 index 0000000000..b903d9b1bc --- /dev/null +++ b/internal/core/src/segcore/IndexConfigGenerator.cpp @@ -0,0 +1,70 @@ +// 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 "IndexConfigGenerator.h" +#include "log/Log.h" + +namespace milvus::segcore { + +VecIndexConfig::VecIndexConfig(const int64_t max_index_row_cout, + const FieldIndexMeta& index_meta_, + const SegcoreConfig& config) + : max_index_row_count_(max_index_row_cout), config_(config) { + origin_index_type_ = index_meta_.GetIndexType(); + metric_type_ = index_meta_.GeMetricType(); + + index_type_ = support_index_types[0]; + build_params_[knowhere::meta::METRIC_TYPE] = metric_type_; + build_params_[knowhere::indexparam::NLIST] = + std::to_string(config_.get_nlist()); + build_params_[knowhere::indexparam::SSIZE] = std::to_string( + std::max((int)(config_.get_chunk_rows() / config_.get_nlist()), 48)); + search_params_[knowhere::indexparam::NPROBE] = + std::to_string(config_.get_nprobe()); + LOG_SEGCORE_INFO_ << " VecIndexConfig: " + << " origin_index_type_:" << origin_index_type_ + << " index_type_: " << index_type_ + << " metric_type_: " << metric_type_; +} + +int64_t +VecIndexConfig::GetBuildThreshold() const noexcept { + assert(VecIndexConfig::index_build_ratio.count(index_type_)); + auto ratio = VecIndexConfig::index_build_ratio.at(index_type_); + assert(ratio >= 0.0 && ratio < 1.0); + return std::max(int64_t(max_index_row_count_ * ratio), + config_.get_nlist() * 39); +} + +knowhere::IndexType +VecIndexConfig::GetIndexType() noexcept { + return index_type_; +} + +knowhere::MetricType +VecIndexConfig::GetMetricType() noexcept { + return metric_type_; +} + +knowhere::Json +VecIndexConfig::GetBuildBaseParams() { + return build_params_; +} + +SearchInfo +VecIndexConfig::GetSearchConf(const SearchInfo& searchInfo) { + SearchInfo searchParam(searchInfo); + searchParam.metric_type_ = metric_type_; + searchParam.search_params_ = search_params_; + return searchParam; +} + +} // namespace milvus::segcore \ No newline at end of file diff --git a/internal/core/src/segcore/IndexConfigGenerator.h b/internal/core/src/segcore/IndexConfigGenerator.h new file mode 100644 index 0000000000..7c146ff224 --- /dev/null +++ b/internal/core/src/segcore/IndexConfigGenerator.h @@ -0,0 +1,71 @@ +// 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 + +#pragma once + +#include "common/Types.h" +#include "common/IndexMeta.h" +#include "knowhere/config.h" +#include "SegcoreConfig.h" +#include "common/QueryInfo.h" + +namespace milvus::segcore { + +enum class IndexConfigLevel { + UNKNOWN = 0, + SUPPORT = 1, + COMPATIBLE = 2, + SYSTEM_ASSIGN = 3 +}; + +class VecIndexConfig { + inline static const std::vector support_index_types = { + knowhere::IndexEnum::INDEX_FAISS_IVFFLAT_CC}; + + inline static const std::map index_build_ratio = { + {knowhere::IndexEnum::INDEX_FAISS_IVFFLAT_CC, 0.1}}; + + public: + VecIndexConfig(const int64_t max_index_row_count, + const FieldIndexMeta& index_meta_, + const SegcoreConfig& config); + + int64_t + GetBuildThreshold() const noexcept; + + knowhere::IndexType + GetIndexType() noexcept; + + knowhere::MetricType + GetMetricType() noexcept; + + knowhere::Json + GetBuildBaseParams(); + + SearchInfo + GetSearchConf(const SearchInfo& searchInfo); + + private: + const SegcoreConfig& config_; + + int64_t max_index_row_count_; + + knowhere::IndexType origin_index_type_; + + knowhere::IndexType index_type_; + + knowhere::MetricType metric_type_; + + knowhere::Json build_params_; + + knowhere::Json search_params_; +}; +} // namespace milvus::segcore \ No newline at end of file diff --git a/internal/core/src/segcore/SegcoreConfig.h b/internal/core/src/segcore/SegcoreConfig.h index dea4605cfd..dc2360a526 100644 --- a/internal/core/src/segcore/SegcoreConfig.h +++ b/internal/core/src/segcore/SegcoreConfig.h @@ -15,29 +15,13 @@ #include #include "common/Types.h" +#include "index/Utils.h" #include "exceptions/EasyAssert.h" #include "utils/Json.h" namespace milvus::segcore { -struct SmallIndexConf { - std::string index_type; - nlohmann::json build_params; - nlohmann::json search_params; -}; - class SegcoreConfig { - private: - SegcoreConfig() { - // hard code configurations for small index - SmallIndexConf sub_conf; - sub_conf.build_params["nlist"] = std::to_string(nlist_); - sub_conf.search_params["nprobe"] = nprobe_; - sub_conf.index_type = "IVF"; - table_[knowhere::metric::L2] = sub_conf; - table_[knowhere::metric::IP] = sub_conf; - } - public: static SegcoreConfig& default_config() { @@ -49,12 +33,6 @@ class SegcoreConfig { void parse_from(const std::string& string_path); - const SmallIndexConf& - at(const MetricType& metric_type) const { - Assert(table_.count(metric_type)); - return table_.at(metric_type); - } - int64_t get_chunk_rows() const { return chunk_rows_; @@ -65,6 +43,16 @@ class SegcoreConfig { chunk_rows_ = chunk_rows; } + int64_t + get_nlist() const { + return nlist_; + } + + int64_t + get_nprobe() const { + return nprobe_; + } + void set_nlist(int64_t nlist) { nlist_ = nlist; @@ -76,16 +64,20 @@ class SegcoreConfig { } void - set_small_index_config(const MetricType& metric_type, - const SmallIndexConf& small_index_conf) { - table_[metric_type] = small_index_conf; + set_enable_growing_segment_index(bool enable_growing_segment_index) { + enable_growing_segment_index_ = enable_growing_segment_index; + } + + bool + get_enable_growing_segment_index() const { + return enable_growing_segment_index_; } private: + bool enable_growing_segment_index_ = false; int64_t chunk_rows_ = 32 * 1024; int64_t nlist_ = 100; int64_t nprobe_ = 4; - std::map table_; }; } // namespace milvus::segcore diff --git a/internal/core/src/segcore/SegmentGrowing.h b/internal/core/src/segcore/SegmentGrowing.h index 3649e3b9c1..87bacf1666 100644 --- a/internal/core/src/segcore/SegmentGrowing.h +++ b/internal/core/src/segcore/SegmentGrowing.h @@ -25,9 +25,6 @@ namespace milvus::segcore { class SegmentGrowing : public SegmentInternalInterface { public: - virtual void - disable_small_index() = 0; - virtual int64_t PreInsert(int64_t size) = 0; diff --git a/internal/core/src/segcore/SegmentGrowingImpl.cpp b/internal/core/src/segcore/SegmentGrowingImpl.cpp index dafd4a20fb..d92b27c674 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.cpp +++ b/internal/core/src/segcore/SegmentGrowingImpl.cpp @@ -86,11 +86,21 @@ SegmentGrowingImpl::Insert(int64_t reserved_offset, for (auto [field_id, field_meta] : schema_->get_fields()) { AssertInfo(field_id_to_offset.count(field_id), "Cannot find field_id"); auto data_offset = field_id_to_offset[field_id]; - insert_record_.get_field_data_base(field_id)->set_data_raw( - reserved_offset, - size, - &insert_data->fields_data(data_offset), - field_meta); + if (!indexing_record_.SyncDataWithIndex(field_id)) { + insert_record_.get_field_data_base(field_id)->set_data_raw( + reserved_offset, + size, + &insert_data->fields_data(data_offset), + field_meta); + } + if (segcore_config_.get_enable_growing_segment_index()) { + indexing_record_.AppendingIndex( + reserved_offset, + size, + field_id, + &insert_data->fields_data(data_offset), + insert_record_); + } } // step 4: set pks to offset @@ -106,12 +116,6 @@ SegmentGrowingImpl::Insert(int64_t reserved_offset, // step 5: update small indexes insert_record_.ack_responder_.AddSegment(reserved_offset, reserved_offset + size); - if (enable_small_index_) { - int64_t chunk_rows = segcore_config_.get_chunk_rows(); - indexing_record_.UpdateResourceAck( - insert_record_.ack_responder_.GetAck() / chunk_rows, - insert_record_); - } } Status @@ -233,13 +237,15 @@ SegmentGrowingImpl::bulk_subscript(FieldId field_id, if (field_meta.is_vector()) { aligned_vector output(field_meta.get_sizeof() * count); if (field_meta.get_data_type() == DataType::VECTOR_FLOAT) { - bulk_subscript_impl(field_meta.get_sizeof(), + bulk_subscript_impl(field_id, + field_meta.get_sizeof(), *vec_ptr, seg_offsets, count, output.data()); } else if (field_meta.get_data_type() == DataType::VECTOR_BINARY) { - bulk_subscript_impl(field_meta.get_sizeof(), + bulk_subscript_impl(field_id, + field_meta.get_sizeof(), *vec_ptr, seg_offsets, count, @@ -315,7 +321,8 @@ SegmentGrowingImpl::bulk_subscript(FieldId field_id, template void -SegmentGrowingImpl::bulk_subscript_impl(int64_t element_sizeof, +SegmentGrowingImpl::bulk_subscript_impl(FieldId field_id, + int64_t element_sizeof, const VectorBase& vec_raw, const int64_t* seg_offsets, int64_t count, @@ -325,14 +332,21 @@ SegmentGrowingImpl::bulk_subscript_impl(int64_t element_sizeof, AssertInfo(vec_ptr, "Pointer of vec_raw is nullptr"); auto& vec = *vec_ptr; std::vector empty(element_sizeof, 0); - auto output_base = reinterpret_cast(output_raw); - for (int i = 0; i < count; ++i) { - auto dst = output_base + i * element_sizeof; - auto offset = seg_offsets[i]; - const uint8_t* src = (offset == INVALID_SEG_OFFSET - ? empty.data() - : (const uint8_t*)vec.get_element(offset)); - memcpy(dst, src, element_sizeof); + + if (indexing_record_.SyncDataWithIndex(field_id)) { + indexing_record_.GetDataFromIndex( + field_id, seg_offsets, count, element_sizeof, output_raw); + } else { + auto output_base = reinterpret_cast(output_raw); + for (int i = 0; i < count; ++i) { + auto dst = output_base + i * element_sizeof; + auto offset = seg_offsets[i]; + const uint8_t* src = + (offset == INVALID_SEG_OFFSET + ? empty.data() + : (const uint8_t*)vec.get_element(offset)); + memcpy(dst, src, element_sizeof); + } } } diff --git a/internal/core/src/segcore/SegmentGrowingImpl.h b/internal/core/src/segcore/SegmentGrowingImpl.h index 51a76b6ed5..bfbd9c8fdd 100644 --- a/internal/core/src/segcore/SegmentGrowingImpl.h +++ b/internal/core/src/segcore/SegmentGrowingImpl.h @@ -33,6 +33,7 @@ #include "query/PlanNode.h" #include "query/deprecated/GeneralQuery.h" #include "utils/Status.h" +#include "common/IndexMeta.h" namespace milvus::segcore { @@ -124,12 +125,6 @@ class SegmentGrowingImpl : public SegmentGrowing { } public: - // only for debug - void - disable_small_index() override { - enable_small_index_ = false; - } - int64_t get_row_count() const override { return insert_record_.ack_responder_.GetAck(); @@ -153,7 +148,8 @@ class SegmentGrowingImpl : public SegmentGrowing { template void - bulk_subscript_impl(int64_t element_sizeof, + bulk_subscript_impl(FieldId field_id, + int64_t element_sizeof, const VectorBase& vec_raw, const int64_t* seg_offsets, int64_t count, @@ -177,12 +173,14 @@ class SegmentGrowingImpl : public SegmentGrowing { int64_t segment_id); explicit SegmentGrowingImpl(SchemaPtr schema, + IndexMetaPtr indexMeta, const SegcoreConfig& segcore_config, int64_t segment_id) : segcore_config_(segcore_config), schema_(std::move(schema)), + index_meta_(indexMeta), insert_record_(*schema_, segcore_config.get_chunk_rows()), - indexing_record_(*schema_, segcore_config_), + indexing_record_(*schema_, index_meta_, segcore_config_), id_(segment_id) { } @@ -243,6 +241,7 @@ class SegmentGrowingImpl : public SegmentGrowing { private: SegcoreConfig segcore_config_; SchemaPtr schema_; + IndexMetaPtr index_meta_; // small indexes for every chunk IndexingRecord indexing_record_; @@ -255,17 +254,20 @@ class SegmentGrowingImpl : public SegmentGrowing { mutable DeletedRecord deleted_record_; int64_t id_; - - private: - bool enable_small_index_ = true; }; +const static IndexMetaPtr empty_index_meta = + std::make_shared(1024, + std::map()); + inline SegmentGrowingPtr CreateGrowingSegment( SchemaPtr schema, + IndexMetaPtr indexMeta, int64_t segment_id = -1, const SegcoreConfig& conf = SegcoreConfig::default_config()) { - return std::make_unique(schema, conf, segment_id); + return std::make_unique( + schema, indexMeta, conf, segment_id); } } // namespace milvus::segcore diff --git a/internal/core/src/segcore/collection_c.cpp b/internal/core/src/segcore/collection_c.cpp index ab2062ec42..4c9eeaf0bd 100644 --- a/internal/core/src/segcore/collection_c.cpp +++ b/internal/core/src/segcore/collection_c.cpp @@ -24,6 +24,13 @@ NewCollection(const char* schema_proto_blob) { return (void*)collection.release(); } +void +SetIndexMeta(CCollection collection, const char* index_meta_proto_blob) { + auto col = (milvus::segcore::Collection*)collection; + auto proto = std::string_view(index_meta_proto_blob); + col->parseIndexMeta(proto); +} + void DeleteCollection(CCollection collection) { auto col = (milvus::segcore::Collection*)collection; diff --git a/internal/core/src/segcore/collection_c.h b/internal/core/src/segcore/collection_c.h index 28f7530998..12c14274b9 100644 --- a/internal/core/src/segcore/collection_c.h +++ b/internal/core/src/segcore/collection_c.h @@ -20,6 +20,9 @@ typedef void* CCollection; CCollection NewCollection(const char* schema_proto_blob); +void +SetIndexMeta(CCollection collection, const char* index_meta_proto_blob); + void DeleteCollection(CCollection collection); diff --git a/internal/core/src/segcore/segcore_init_c.cpp b/internal/core/src/segcore/segcore_init_c.cpp index 26f4a486b0..2aa14984aa 100644 --- a/internal/core/src/segcore/segcore_init_c.cpp +++ b/internal/core/src/segcore/segcore_init_c.cpp @@ -28,6 +28,13 @@ SegcoreSetChunkRows(const int64_t value) { config.set_chunk_rows(value); } +extern "C" void +SegcoreSetEnableGrowingSegmentIndex(const bool value) { + milvus::segcore::SegcoreConfig& config = + milvus::segcore::SegcoreConfig::default_config(); + config.set_enable_growing_segment_index(value); +} + extern "C" void SegcoreSetNlist(const int64_t value) { milvus::segcore::SegcoreConfig& config = diff --git a/internal/core/src/segcore/segcore_init_c.h b/internal/core/src/segcore/segcore_init_c.h index 006de8c75b..8aef256e61 100644 --- a/internal/core/src/segcore/segcore_init_c.h +++ b/internal/core/src/segcore/segcore_init_c.h @@ -21,6 +21,9 @@ SegcoreInit(const char*); void SegcoreSetChunkRows(const int64_t); +void +SegcoreSetEnableGrowingSegmentIndex(const bool); + void SegcoreSetNlist(const int64_t); diff --git a/internal/core/src/segcore/segment_c.cpp b/internal/core/src/segcore/segment_c.cpp index 09d096fc85..e3e93d90c8 100644 --- a/internal/core/src/segcore/segment_c.cpp +++ b/internal/core/src/segcore/segment_c.cpp @@ -22,6 +22,7 @@ #include "segcore/Collection.h" #include "segcore/SegmentGrowingImpl.h" #include "segcore/SegmentSealedImpl.h" +#include "segcore/SegcoreConfig.h" ////////////////////////////// common interfaces ////////////////////////////// CSegmentInterface @@ -31,9 +32,8 @@ NewSegment(CCollection collection, SegmentType seg_type, int64_t segment_id) { std::unique_ptr segment; switch (seg_type) { case Growing: { - auto seg = milvus::segcore::CreateGrowingSegment(col->get_schema(), - segment_id); - seg->disable_small_index(); + auto seg = milvus::segcore::CreateGrowingSegment( + col->get_schema(), col->GetIndexMeta(), segment_id); segment = std::move(seg); break; } diff --git a/internal/core/thirdparty/knowhere/CMakeLists.txt b/internal/core/thirdparty/knowhere/CMakeLists.txt index 3e63bedc7c..5cc0c688f6 100644 --- a/internal/core/thirdparty/knowhere/CMakeLists.txt +++ b/internal/core/thirdparty/knowhere/CMakeLists.txt @@ -11,7 +11,7 @@ # or implied. See the License for the specific language governing permissions and limitations under the License. #------------------------------------------------------------------------------- -set( KNOWHERE_VERSION b2cab04 ) +set( KNOWHERE_VERSION d70aa43) message(STATUS "Building knowhere-${KNOWHERE_SOURCE_VER} from source") message(STATUS ${CMAKE_BUILD_TYPE}) diff --git a/internal/core/unittest/CMakeLists.txt b/internal/core/unittest/CMakeLists.txt index ad722e7093..13fd9f6a22 100644 --- a/internal/core/unittest/CMakeLists.txt +++ b/internal/core/unittest/CMakeLists.txt @@ -26,6 +26,7 @@ set(MILVUS_TEST_FILES test_c_api.cpp test_expr.cpp test_growing.cpp + test_growing_index.cpp test_indexing.cpp test_index_c_api.cpp test_index_wrapper.cpp diff --git a/internal/core/unittest/bench/bench_search.cpp b/internal/core/unittest/bench/bench_search.cpp index cea4690650..4b3c2e8628 100644 --- a/internal/core/unittest/bench/bench_search.cpp +++ b/internal/core/unittest/bench/bench_search.cpp @@ -63,7 +63,7 @@ auto ph_group = [] { }(); static void -Search_SmallIndex(benchmark::State& state) { +Search_GrowingIndex(benchmark::State& state) { // schema->AddDebugField("age", DataType::FLOAT); static int64_t N = 1024 * 32; @@ -72,14 +72,24 @@ Search_SmallIndex(benchmark::State& state) { return dataset_; }(); - auto is_small_index = state.range(0); auto chunk_rows = state.range(1) * 1024; auto segconf = SegcoreConfig::default_config(); segconf.set_chunk_rows(chunk_rows); - auto segment = CreateGrowingSegment(schema, -1, segconf); - if (!is_small_index) { - segment->disable_small_index(); - } + + std::map index_params = { + {"index_type", "IVF_FLAT"}, {"metric_type", "L2"}, {"nlist", "128"}}; + std::map type_params = {{"dim", "128"}}; + FieldIndexMeta fieldIndexMeta(schema->get_field_id(FieldName("fakevec")), + std::move(index_params), + std::move(type_params)); + segconf.set_enable_growing_segment_index(true); + std::map filedMap = { + {schema->get_field_id(FieldName("fakevec")), fieldIndexMeta}}; + IndexMetaPtr metaPtr = + std::make_shared(226985, std::move(filedMap)); + + auto segment = CreateGrowingSegment(schema, metaPtr, -1, segconf); + segment->PreInsert(N); segment->Insert(0, N, @@ -94,7 +104,7 @@ Search_SmallIndex(benchmark::State& state) { } } -BENCHMARK(Search_SmallIndex) +BENCHMARK(Search_GrowingIndex) ->MinTime(5) ->ArgsProduct({{true, false}, {8, 16, 32}}); diff --git a/internal/core/unittest/test_binary.cpp b/internal/core/unittest/test_binary.cpp index 2308773d4a..05e80559cd 100644 --- a/internal/core/unittest/test_binary.cpp +++ b/internal/core/unittest/test_binary.cpp @@ -23,7 +23,7 @@ TEST(Binary, Insert) { auto i64_fid = schema->AddDebugField("age", DataType::INT64); schema->set_primary_field_id(i64_fid); auto dataset = DataGen(schema, N, 10); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); auto offset = segment->PreInsert(N); segment->Insert(offset, N, diff --git a/internal/core/unittest/test_c_api.cpp b/internal/core/unittest/test_c_api.cpp index 1cc07883e0..62d1db6a52 100644 --- a/internal/core/unittest/test_c_api.cpp +++ b/internal/core/unittest/test_c_api.cpp @@ -72,6 +72,33 @@ get_default_schema_config() { return conf.c_str(); } +const char* +get_default_index_meta() { + static std::string conf = R"(maxIndexRowCount: 1000 + index_metas: < + fieldID: 100 + collectionID: 1001 + index_name: "test-index" + type_params: < + key: "dim" + value: "16" + > + index_params: < + key: "index_type" + value: "IVF_FLAT" + > + index_params: < + key: "metric_type" + value: "L2" + > + index_params: < + key: "nlist" + value: "128" + > + >)"; + return conf.c_str(); +} + auto generate_data(int N) { std::vector raw_data; @@ -227,6 +254,12 @@ TEST(CApiTest, CollectionTest) { DeleteCollection(collection); } +TEST(CApiTest, SetIndexMetaTest) { + auto collection = NewCollection(get_default_schema_config()); + SetIndexMeta(collection, get_default_index_meta()); + DeleteCollection(collection); +} + TEST(CApiTest, GetCollectionNameTest) { auto collection = NewCollection(get_default_schema_config()); auto name = GetCollectionName(collection); @@ -1699,7 +1732,8 @@ TEST(CApiTest, LoadIndex_Search) { auto N = 1024 * 10; auto num_query = 100; auto [raw_data, timestamps, uids] = generate_data(N); - auto indexing = knowhere::IndexFactory::Instance().Create(knowhere::IndexEnum::INDEX_FAISS_IVFSQ8); + auto indexing = knowhere::IndexFactory::Instance().Create( + knowhere::IndexEnum::INDEX_FAISS_IVFSQ8); auto conf = knowhere::Json{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2}, {knowhere::meta::DIM, DIM}, @@ -1722,11 +1756,13 @@ TEST(CApiTest, LoadIndex_Search) { milvus::segcore::LoadIndexInfo load_index_info; auto& index_params = load_index_info.index_params; index_params["index_type"] = knowhere::IndexEnum::INDEX_FAISS_IVFSQ8; - load_index_info.index = std::make_unique(index_params["index_type"], knowhere::metric::L2); + load_index_info.index = std::make_unique( + index_params["index_type"], knowhere::metric::L2); load_index_info.index->Load(binary_set); // search - auto query_dataset = knowhere::GenDataSet(num_query, DIM, raw_data.data() + BIAS * DIM); + auto query_dataset = + knowhere::GenDataSet(num_query, DIM, raw_data.data() + BIAS * DIM); auto result = indexing.Search(*query_dataset, conf, nullptr); @@ -1741,7 +1777,8 @@ TEST(CApiTest, Indexing_Without_Predicate) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -1891,7 +1928,8 @@ TEST(CApiTest, Indexing_Expr_Without_Predicate) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -2037,7 +2075,8 @@ TEST(CApiTest, Indexing_With_float_Predicate_Range) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -2197,7 +2236,8 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Range) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -2372,7 +2412,8 @@ TEST(CApiTest, Indexing_With_float_Predicate_Term) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -2530,7 +2571,8 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Term) { // insert data to segment constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Growing, -1); @@ -3433,7 +3475,8 @@ TEST(CApiTest, SealedSegmentTest) { TEST(CApiTest, SealedSegment_search_float_Predicate_Range) { constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Sealed, -1); @@ -3602,7 +3645,8 @@ TEST(CApiTest, SealedSegment_search_float_Predicate_Range) { TEST(CApiTest, SealedSegment_search_without_predicates) { constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Sealed, -1); @@ -3724,7 +3768,8 @@ TEST(CApiTest, SealedSegment_search_without_predicates) { TEST(CApiTest, SealedSegment_search_float_With_Expr_Predicate_Range) { constexpr auto TOPK = 5; - std::string schema_string = generate_collection_schema(knowhere::metric::L2, DIM, false); + std::string schema_string = + generate_collection_schema(knowhere::metric::L2, DIM, false); auto collection = NewCollection(schema_string.c_str()); auto schema = ((segcore::Collection*)collection)->get_schema(); auto segment = NewSegment(collection, Sealed, -1); diff --git a/internal/core/unittest/test_expr.cpp b/internal/core/unittest/test_expr.cpp index 2ac370390e..98c9541dd9 100644 --- a/internal/core/unittest/test_expr.cpp +++ b/internal/core/unittest/test_expr.cpp @@ -306,7 +306,7 @@ TEST(Expr, TestRange) { auto i64_fid = schema->AddDebugField("age", DataType::INT64); schema->set_primary_field_id(i64_fid); - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector age_col; int num_iters = 100; @@ -395,7 +395,7 @@ TEST(Expr, TestTerm) { auto i64_fid = schema->AddDebugField("age", DataType::INT64); schema->set_primary_field_id(i64_fid); - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector age_col; int num_iters = 100; @@ -510,7 +510,7 @@ TEST(Expr, TestSimpleDsl) { auto i64_fid = schema->AddDebugField("age", DataType::INT64); schema->set_primary_field_id(i64_fid); - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); std::vector age_col; int num_iters = 100; for (int iter = 0; iter < num_iters; ++iter) { @@ -592,7 +592,7 @@ TEST(Expr, TestCompare) { auto i64_fid = schema->AddDebugField("age2", DataType::INT64); schema->set_primary_field_id(i64_fid); - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector age1_col; std::vector age2_col; @@ -1009,7 +1009,7 @@ TEST(Expr, TestBinaryArithOpEvalRange) { auto double_fid = schema->AddDebugField("age_double", DataType::DOUBLE); schema->set_primary_field_id(i64_fid); - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector age8_col; std::vector age16_col; diff --git a/internal/core/unittest/test_growing.cpp b/internal/core/unittest/test_growing.cpp index 416e4f5504..a3d45e37bc 100644 --- a/internal/core/unittest/test_growing.cpp +++ b/internal/core/unittest/test_growing.cpp @@ -24,7 +24,7 @@ TEST(Growing, DeleteCount) { auto schema = std::make_shared(); auto pk = schema->AddDebugField("pk", DataType::INT64); schema->set_primary_field_id(pk); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); int64_t c = 10; auto offset = segment->PreDelete(c); @@ -44,7 +44,7 @@ TEST(Growing, RealCount) { auto schema = std::make_shared(); auto pk = schema->AddDebugField("pk", DataType::INT64); schema->set_primary_field_id(pk); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); int64_t c = 10; auto offset = segment->PreInsert(c); diff --git a/internal/core/unittest/test_growing_index.cpp b/internal/core/unittest/test_growing_index.cpp new file mode 100644 index 0000000000..610ba12d73 --- /dev/null +++ b/internal/core/unittest/test_growing_index.cpp @@ -0,0 +1,141 @@ +// 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 "segcore/SegmentGrowing.h" +#include "segcore/SegmentGrowingImpl.h" +#include "pb/schema.pb.h" +#include "test_utils/DataGen.h" +#include "query/Plan.h" + +using namespace milvus::segcore; +using namespace milvus; +namespace pb = milvus::proto; + +TEST(GrowingIndex, Correctness) { + auto schema = std::make_shared(); + auto pk = schema->AddDebugField("pk", DataType::INT64); + auto random = schema->AddDebugField("random", DataType::DOUBLE); + auto vec = schema->AddDebugField( + "embeddings", DataType::VECTOR_FLOAT, 128, knowhere::metric::L2); + schema->set_primary_field_id(pk); + + std::map index_params = { + {"index_type", "IVF_FLAT"}, {"metric_type", "L2"}, {"nlist", "128"}}; + std::map type_params = {{"dim", "128"}}; + FieldIndexMeta fieldIndexMeta( + vec, std::move(index_params), std::move(type_params)); + auto& config = SegcoreConfig::default_config(); + config.set_chunk_rows(1024); + config.set_enable_growing_segment_index(true); + std::map filedMap = {{vec, fieldIndexMeta}}; + IndexMetaPtr metaPtr = + std::make_shared(226985, std::move(filedMap)); + auto segment = CreateGrowingSegment(schema, metaPtr); + + std::string dsl = R"({ + "bool": { + "must": [ + { + "vector": { + "embeddings": { + "metric_type": "l2", + "params": { + "nprobe": 16 + }, + "query": "$0", + "topk": 5, + "round_decimal":3 + } + } + } + ] + } + })"; + + int64_t per_batch = 10000; + int64_t n_batch = 20; + int64_t top_k = 5; + for (int64_t i = 0; i < n_batch; i++) { + auto dataset = DataGen(schema, per_batch); + auto offset = segment->PreInsert(per_batch); + auto pks = dataset.get_col(pk); + segment->Insert(offset, + per_batch, + dataset.row_ids_.data(), + dataset.timestamps_.data(), + dataset.raw_); + + auto plan = milvus::query::CreatePlan(*schema, dsl); + auto num_queries = 5; + auto ph_group_raw = CreatePlaceholderGroup(num_queries, 128, 1024); + auto ph_group = + ParsePlaceholderGroup(plan.get(), ph_group_raw.SerializeAsString()); + Timestamp time = 1000000; + auto sr = segment->Search(plan.get(), ph_group.get(), time); + EXPECT_EQ(sr->total_nq_, num_queries); + EXPECT_EQ(sr->unity_topK_, top_k); + EXPECT_EQ(sr->distances_.size(), num_queries * top_k); + EXPECT_EQ(sr->seg_offsets_.size(), num_queries * top_k); + } +} + +TEST(GrowingIndex, GetVector) { + auto schema = std::make_shared(); + auto pk = schema->AddDebugField("pk", DataType::INT64); + auto random = schema->AddDebugField("random", DataType::DOUBLE); + auto vec = schema->AddDebugField( + "embeddings", DataType::VECTOR_FLOAT, 128, knowhere::metric::L2); + schema->set_primary_field_id(pk); + + std::map index_params = { + {"index_type", "IVF_FLAT"}, {"metric_type", "L2"}, {"nlist", "128"}}; + std::map type_params = {{"dim", "128"}}; + FieldIndexMeta fieldIndexMeta( + vec, std::move(index_params), std::move(type_params)); + auto& config = SegcoreConfig::default_config(); + config.set_chunk_rows(1024); + config.set_enable_growing_segment_index(true); + std::map filedMap = {{vec, fieldIndexMeta}}; + IndexMetaPtr metaPtr = + std::make_shared(100000, std::move(filedMap)); + auto segment_growing = CreateGrowingSegment(schema, metaPtr); + auto segment = dynamic_cast(segment_growing.get()); + + int64_t per_batch = 5000; + int64_t n_batch = 20; + int64_t dim = 128; + for (int64_t i = 0; i < n_batch; i++) { + auto dataset = DataGen(schema, per_batch); + auto fakevec = dataset.get_col(vec); + auto offset = segment->PreInsert(per_batch); + segment->Insert(offset, + per_batch, + dataset.row_ids_.data(), + dataset.timestamps_.data(), + dataset.raw_); + auto num_inserted = (i + 1) * per_batch; + auto ids_ds = GenRandomIds(num_inserted); + auto result = + segment->bulk_subscript(vec, ids_ds->GetIds(), num_inserted); + + auto vector = result.get()->mutable_vectors()->float_vector().data(); + EXPECT_TRUE(vector.size() == num_inserted * dim); + for (size_t i = 0; i < num_inserted; ++i) { + auto id = ids_ds->GetIds()[i]; + for (size_t j = 0; j < 128; ++j) { + EXPECT_TRUE(vector[i * dim + j] == + fakevec[(id % per_batch) * dim + j]); + } + } + } +} diff --git a/internal/core/unittest/test_minio_chunk_manager.cpp b/internal/core/unittest/test_minio_chunk_manager.cpp index 5c4e9cb503..9d42931f2e 100644 --- a/internal/core/unittest/test_minio_chunk_manager.cpp +++ b/internal/core/unittest/test_minio_chunk_manager.cpp @@ -30,7 +30,8 @@ class MinioChunkManagerTest : public testing::Test { virtual void SetUp() { - chunk_manager_ = std::make_unique(get_default_storage_config()); + chunk_manager_ = + std::make_unique(get_default_storage_config()); } protected: @@ -48,7 +49,15 @@ get_google_cloud_storage_config() { auto iamEndPoint = ""; auto bucketName = "gcp-zilliz-infra-test"; - return StorageConfig{endpoint, bucketName, accessKey, accessValue, rootPath, "minio", iamEndPoint, useSSL, useIam}; + return StorageConfig{endpoint, + bucketName, + accessKey, + accessValue, + rootPath, + "minio", + iamEndPoint, + useSSL, + useIam}; } StorageConfig @@ -62,7 +71,15 @@ get_aliyun_cloud_storage_config() { auto iamEndPoint = ""; auto bucketName = "vdc-infra-poc"; - return StorageConfig{endpoint, bucketName, accessKey, accessValue, rootPath, "minio", iamEndPoint, useSSL, useIam}; + return StorageConfig{endpoint, + bucketName, + accessKey, + accessValue, + rootPath, + "minio", + iamEndPoint, + useSSL, + useIam}; } class AliyunChunkManagerTest : public testing::Test { @@ -74,7 +91,8 @@ class AliyunChunkManagerTest : public testing::Test { virtual void SetUp() { - chunk_manager_ = std::make_unique(get_aliyun_cloud_storage_config()); + chunk_manager_ = std::make_unique( + get_aliyun_cloud_storage_config()); } protected: diff --git a/internal/core/unittest/test_query.cpp b/internal/core/unittest/test_query.cpp index 0f0023efad..e51b02b7b6 100644 --- a/internal/core/unittest/test_query.cpp +++ b/internal/core/unittest/test_query.cpp @@ -176,7 +176,7 @@ TEST(Query, ExecWithPredicateLoader) { })"; int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -199,22 +199,22 @@ TEST(Query, ExecWithPredicateLoader) { auto ref = json::parse(R"( [ [ - ["982->0.000000", "25315->4.742000", "57893->4.758000", "1499->6.066000", "48201->6.075000"], - ["41772->10.111000", "80693->11.712000", "74859->11.790000", "79777->11.842000", "31878->12.308000"], - ["65551->4.454000", "21617->5.144000", "50037->5.267000", "72204->5.332000", "96905->5.479000"], - ["59219->5.458000", "21995->6.078000", "61367->7.029000", "44657->7.031000", "66957->7.174000"], - ["66353->5.696000", "41087->5.917000", "97780->6.811000", "99239->7.562000", "86527->7.751000"] + ["982->0.000000", "25315->4.742000", "57893->4.758000", "1499->6.066000", "48201->6.075000"], + ["41772->10.111000", "42126->11.532000", "80693->11.712000", "74859->11.790000", "79777->11.842000"], + ["59251->2.543000", "65551->4.454000", "21617->5.144000", "50037->5.267000", "72204->5.332000"], + ["59219->5.458000", "21995->6.078000", "97922->6.764000", "80887->6.898000", "61367->7.029000"], + ["66353->5.696000", "30664->5.881000", "41087->5.917000", "34625->6.109000", "10393->6.633000"] ] ])"); #else // for mac auto ref = json::parse(R"( [ [ - ["982->0.000000", "31864->4.270000", "18916->4.651000", "71547->5.125000", "13227->6.010000"], + ["982->0.000000", "31864->4.270000", "18916->4.651000", "71547->5.125000", "86706->5.991000"], ["96984->4.192000", "65514->6.011000", "89328->6.138000", "80284->6.526000", "68218->6.563000"], - ["30119->2.464000", "52595->4.323000", "32673->4.851000", "74834->5.009000", "50806->5.446000"], + ["30119->2.464000", "52595->4.323000", "82365->4.725000", "32673->4.851000", "74834->5.009000"], ["99625->6.129000", "86582->6.900000", "10069->7.388000", "89982->7.672000", "85934->7.792000"], - ["37759->3.581000", "97019->5.557000", "53543->5.844000", "63535->6.439000", "94009->6.572000"] + ["37759->3.581000", "97019->5.557000", "92444->5.681000", "31292->5.780000", "53543->5.844000"] ] ])"); #endif @@ -260,7 +260,7 @@ TEST(Query, ExecWithPredicateSmallN) { })"; int64_t N = 177; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -320,7 +320,7 @@ TEST(Query, ExecWithPredicate) { })"; int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -344,21 +344,21 @@ TEST(Query, ExecWithPredicate) { [ [ ["982->0.000000", "25315->4.742000", "57893->4.758000", "1499->6.066000", "48201->6.075000"], - ["41772->10.111000", "80693->11.712000", "74859->11.790000", "79777->11.842000", "31878->12.308000"], - ["65551->4.454000", "21617->5.144000", "50037->5.267000", "72204->5.332000", "96905->5.479000"], - ["59219->5.458000", "21995->6.078000", "61367->7.029000", "44657->7.031000", "66957->7.174000"], - ["66353->5.696000", "41087->5.917000", "97780->6.811000", "99239->7.562000", "86527->7.751000"] + ["41772->10.111000", "42126->11.532000", "80693->11.712000", "74859->11.790000", "79777->11.842000"], + ["59251->2.543000", "65551->4.454000", "21617->5.144000", "50037->5.267000", "72204->5.332000"], + ["59219->5.458000", "21995->6.078000", "97922->6.764000", "80887->6.898000", "61367->7.029000"], + ["66353->5.696000", "30664->5.881000", "41087->5.917000", "34625->6.109000", "10393->6.633000"] ] ])"); #else // for mac auto ref = json::parse(R"( [ [ - ["982->0.000000", "31864->4.270000", "18916->4.651000", "71547->5.125000", "13227->6.010000"], + ["982->0.000000", "31864->4.270000", "18916->4.651000", "71547->5.125000", "86706->5.991000"], ["96984->4.192000", "65514->6.011000", "89328->6.138000", "80284->6.526000", "68218->6.563000"], - ["30119->2.464000", "52595->4.323000", "32673->4.851000", "74834->5.009000", "50806->5.446000"], + ["30119->2.464000", "52595->4.323000", "82365->4.725000", "32673->4.851000", "74834->5.009000"], ["99625->6.129000", "86582->6.900000", "10069->7.388000", "89982->7.672000", "85934->7.792000"], - ["37759->3.581000", "97019->5.557000", "53543->5.844000", "63535->6.439000", "94009->6.572000"] + ["37759->3.581000", "97019->5.557000", "92444->5.681000", "31292->5.780000", "53543->5.844000"] ] ])"); #endif @@ -403,7 +403,7 @@ TEST(Query, ExecTerm) { })"; int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -454,7 +454,7 @@ TEST(Query, ExecEmpty) { } })"; int64_t N = ROW_COUNT; - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); auto plan = CreatePlan(*schema, dsl); auto num_queries = 5; auto ph_group_raw = CreatePlaceholderGroup(num_queries, 16, 1024); @@ -504,7 +504,7 @@ TEST(Query, ExecWithoutPredicateFlat) { auto plan = CreatePlan(*schema, dsl); int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -556,7 +556,7 @@ TEST(Query, ExecWithoutPredicate) { auto plan = CreatePlan(*schema, dsl); int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -580,10 +580,10 @@ TEST(Query, ExecWithoutPredicate) { [ [ ["982->0.000000", "25315->4.742000", "57893->4.758000", "1499->6.066000", "48201->6.075000"], - ["41772->10.111000", "80693->11.712000", "74859->11.790000", "79777->11.842000", "31878->12.308000"], - ["65551->4.454000", "21617->5.144000", "50037->5.267000", "98268->5.321000", "72204->5.332000"], - ["33572->5.432000", "59219->5.458000", "21995->6.078000", "17913->6.831000", "86628->6.835000"], - ["66353->5.696000", "41087->5.917000", "24554->6.195000", "68019->6.654000", "97780->6.811000"] + ["41772->10.111000", "42126->11.532000", "80693->11.712000", "74859->11.790000", "79777->11.842000"], + ["59251->2.543000", "68714->4.356000", "65551->4.454000", "21617->5.144000", "50037->5.267000"], + ["33572->5.432000", "59219->5.458000", "21995->6.078000", "97922->6.764000", "17913->6.831000"], + ["66353->5.696000", "30664->5.881000", "41087->5.917000", "34625->6.109000", "24554->6.195000"] ] ])"); #else // for mac @@ -592,9 +592,9 @@ TEST(Query, ExecWithoutPredicate) { [ ["982->0.000000", "31864->4.270000", "18916->4.651000", "78227->4.808000", "71547->5.125000"], ["96984->4.192000", "45733->4.912000", "32891->5.016000", "65514->6.011000", "89328->6.138000"], - ["30119->2.464000", "52595->4.323000", "32673->4.851000", "74834->5.009000", "76784->5.195000"], + ["30119->2.464000", "23782->3.724000", "52595->4.323000", "82365->4.725000", "32673->4.851000"], ["99625->6.129000", "86582->6.900000", "60608->7.285000", "10069->7.388000", "89982->7.672000"], - ["37759->3.581000", "45814->4.872000", "97019->5.557000", "23626->5.839000", "53543->5.844000"] + ["37759->3.581000", "50907->4.776000", "45814->4.872000", "97019->5.557000", "92444->5.681000"] ] ])"); #endif @@ -632,7 +632,7 @@ TEST(Query, InnerProduct) { auto i64_fid = schema->AddDebugField("age", DataType::INT64); schema->set_primary_field_id(i64_fid); auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); auto plan = CreatePlan(*schema, dsl); segment->PreInsert(N); segment->Insert(0, @@ -706,7 +706,7 @@ TEST(Query, FillSegment) { std::vector> segments; segments.emplace_back([&] { - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -854,7 +854,7 @@ TEST(Query, ExecWithPredicateBinary) { })"; int64_t N = ROW_COUNT; auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, diff --git a/internal/core/unittest/test_sealed.cpp b/internal/core/unittest/test_sealed.cpp index e0b480ccc6..d850392ac3 100644 --- a/internal/core/unittest/test_sealed.cpp +++ b/internal/core/unittest/test_sealed.cpp @@ -65,7 +65,7 @@ TEST(Sealed, without_predicate) { vec_col.push_back(0); } auto query_ptr = vec_col.data() + BIAS * dim; - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -182,7 +182,7 @@ TEST(Sealed, with_predicate) { auto dataset = DataGen(schema, N); auto vec_col = dataset.get_col(fake_id); auto query_ptr = vec_col.data() + BIAS * dim; - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, diff --git a/internal/core/unittest/test_segcore.cpp b/internal/core/unittest/test_segcore.cpp index 54ab0b79be..1391de907a 100644 --- a/internal/core/unittest/test_segcore.cpp +++ b/internal/core/unittest/test_segcore.cpp @@ -57,7 +57,7 @@ TEST(SegmentCoreTest, NormalDistributionTest) { schema->AddDebugField("age", DataType::INT32); int N = 100 * 1000; auto [raw_data, timestamps, uids] = generate_data(N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->PreDelete(N); } @@ -75,7 +75,7 @@ TEST(SegmentCoreTest, MockTest2) { int N = 10000; // number of records auto dataset = DataGen(schema, N); - auto segment = CreateGrowingSegment(schema); + auto segment = CreateGrowingSegment(schema, empty_index_meta); auto reserved_begin = segment->PreInsert(N); segment->Insert(reserved_begin, N, diff --git a/internal/core/unittest/test_span.cpp b/internal/core/unittest/test_span.cpp index dd99cfbe7c..721cc18c54 100644 --- a/internal/core/unittest/test_span.cpp +++ b/internal/core/unittest/test_span.cpp @@ -33,7 +33,7 @@ TEST(Span, Naive) { auto dataset = DataGen(schema, N); auto seg_conf = SegcoreConfig::default_config(); - auto segment = CreateGrowingSegment(schema, -1, seg_conf); + auto segment = CreateGrowingSegment(schema, empty_index_meta, -1, seg_conf); segment->PreInsert(N); segment->Insert(0, N, diff --git a/internal/core/unittest/test_string_expr.cpp b/internal/core/unittest/test_string_expr.cpp index 782ea3cbb2..67a04917fa 100644 --- a/internal/core/unittest/test_string_expr.cpp +++ b/internal/core/unittest/test_string_expr.cpp @@ -287,7 +287,7 @@ TEST(StringExpr, Term) { {4, {vec_2k_3k}}, }; - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector str_col; int num_iters = 100; @@ -385,7 +385,7 @@ TEST(StringExpr, Compare) { }}, }; - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector str_col; std::vector another_str_col; @@ -488,7 +488,7 @@ TEST(StringExpr, UnaryRange) { [](std::string val) { return PrefixMatch(val, "a"); }}, }; - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector str_col; int num_iters = 100; @@ -592,7 +592,7 @@ TEST(StringExpr, BinaryRange) { {true, true, "2000", "1000", [](std::string val) { return false; }}, }; - auto seg = CreateGrowingSegment(schema); + auto seg = CreateGrowingSegment(schema, empty_index_meta); int N = 1000; std::vector str_col; int num_iters = 100; @@ -649,8 +649,7 @@ TEST(AlwaysTrueStringPlan, SearchWithOutputFields) { auto str_col = dataset.get_col(str_meta.get_id())->scalars().string_data().data(); auto query_ptr = vec_col.data(); - auto segment = CreateGrowingSegment(schema); - segment->disable_small_index(); // brute-force search. + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, @@ -716,8 +715,7 @@ TEST(AlwaysTrueStringPlan, QueryWithOutputFields) { auto vec_col = dataset.get_col(fvec_meta.get_id()); auto str_col = dataset.get_col(str_meta.get_id())->scalars().string_data().data(); - auto segment = CreateGrowingSegment(schema); - segment->disable_small_index(); // brute-force search. + auto segment = CreateGrowingSegment(schema, empty_index_meta); segment->PreInsert(N); segment->Insert(0, N, diff --git a/internal/proto/query_coord.proto b/internal/proto/query_coord.proto index be89bba66d..529d595d14 100644 --- a/internal/proto/query_coord.proto +++ b/internal/proto/query_coord.proto @@ -10,6 +10,7 @@ import "internal.proto"; import "schema.proto"; import "msg.proto"; import "data_coord.proto"; +import "index_coord.proto"; service QueryCoord { rpc GetComponentStates(milvus.GetComponentStatesRequest) returns (milvus.ComponentStates) {} @@ -218,10 +219,11 @@ message WatchDmChannelsRequest { LoadMetaInfo load_meta = 8; int64 replicaID = 9; map segment_infos = 10; + repeated index.IndexInfo index_info_list = 11; // Deprecated // for node down load balance, need to remove offline node in time after every watchDmChannel finish. - int64 offlineNodeID = 11; - int64 version = 12; + int64 offlineNodeID = 12; + int64 version = 13; } message UnsubDmChannelRequest { diff --git a/internal/proto/querypb/query_coord.pb.go b/internal/proto/querypb/query_coord.pb.go index ad9b5028bd..a2b336cf19 100644 --- a/internal/proto/querypb/query_coord.pb.go +++ b/internal/proto/querypb/query_coord.pb.go @@ -12,6 +12,7 @@ import ( msgpb "github.com/milvus-io/milvus-proto/go-api/msgpb" schemapb "github.com/milvus-io/milvus-proto/go-api/schemapb" datapb "github.com/milvus-io/milvus/internal/proto/datapb" + indexpb "github.com/milvus-io/milvus/internal/proto/indexpb" internalpb "github.com/milvus-io/milvus/internal/proto/internalpb" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -1378,20 +1379,21 @@ func (m *LoadMetaInfo) GetPartitionIDs() []int64 { } type WatchDmChannelsRequest struct { - Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` - NodeID int64 `protobuf:"varint,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"` - CollectionID int64 `protobuf:"varint,3,opt,name=collectionID,proto3" json:"collectionID,omitempty"` - PartitionIDs []int64 `protobuf:"varint,4,rep,packed,name=partitionIDs,proto3" json:"partitionIDs,omitempty"` - Infos []*datapb.VchannelInfo `protobuf:"bytes,5,rep,name=infos,proto3" json:"infos,omitempty"` - Schema *schemapb.CollectionSchema `protobuf:"bytes,6,opt,name=schema,proto3" json:"schema,omitempty"` - ExcludeInfos []*datapb.SegmentInfo `protobuf:"bytes,7,rep,name=exclude_infos,json=excludeInfos,proto3" json:"exclude_infos,omitempty"` - LoadMeta *LoadMetaInfo `protobuf:"bytes,8,opt,name=load_meta,json=loadMeta,proto3" json:"load_meta,omitempty"` - ReplicaID int64 `protobuf:"varint,9,opt,name=replicaID,proto3" json:"replicaID,omitempty"` - SegmentInfos map[int64]*datapb.SegmentInfo `protobuf:"bytes,10,rep,name=segment_infos,json=segmentInfos,proto3" json:"segment_infos,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` + NodeID int64 `protobuf:"varint,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"` + CollectionID int64 `protobuf:"varint,3,opt,name=collectionID,proto3" json:"collectionID,omitempty"` + PartitionIDs []int64 `protobuf:"varint,4,rep,packed,name=partitionIDs,proto3" json:"partitionIDs,omitempty"` + Infos []*datapb.VchannelInfo `protobuf:"bytes,5,rep,name=infos,proto3" json:"infos,omitempty"` + Schema *schemapb.CollectionSchema `protobuf:"bytes,6,opt,name=schema,proto3" json:"schema,omitempty"` + ExcludeInfos []*datapb.SegmentInfo `protobuf:"bytes,7,rep,name=exclude_infos,json=excludeInfos,proto3" json:"exclude_infos,omitempty"` + LoadMeta *LoadMetaInfo `protobuf:"bytes,8,opt,name=load_meta,json=loadMeta,proto3" json:"load_meta,omitempty"` + ReplicaID int64 `protobuf:"varint,9,opt,name=replicaID,proto3" json:"replicaID,omitempty"` + SegmentInfos map[int64]*datapb.SegmentInfo `protobuf:"bytes,10,rep,name=segment_infos,json=segmentInfos,proto3" json:"segment_infos,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + IndexInfoList []*indexpb.IndexInfo `protobuf:"bytes,11,rep,name=index_info_list,json=indexInfoList,proto3" json:"index_info_list,omitempty"` // Deprecated // for node down load balance, need to remove offline node in time after every watchDmChannel finish. - OfflineNodeID int64 `protobuf:"varint,11,opt,name=offlineNodeID,proto3" json:"offlineNodeID,omitempty"` - Version int64 `protobuf:"varint,12,opt,name=version,proto3" json:"version,omitempty"` + OfflineNodeID int64 `protobuf:"varint,12,opt,name=offlineNodeID,proto3" json:"offlineNodeID,omitempty"` + Version int64 `protobuf:"varint,13,opt,name=version,proto3" json:"version,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1492,6 +1494,13 @@ func (m *WatchDmChannelsRequest) GetSegmentInfos() map[int64]*datapb.SegmentInfo return nil } +func (m *WatchDmChannelsRequest) GetIndexInfoList() []*indexpb.IndexInfo { + if m != nil { + return m.IndexInfoList + } + return nil +} + func (m *WatchDmChannelsRequest) GetOfflineNodeID() int64 { if m != nil { return m.OfflineNodeID @@ -4478,293 +4487,295 @@ func init() { func init() { proto.RegisterFile("query_coord.proto", fileDescriptor_aab7cc9a69ed26e8) } var fileDescriptor_aab7cc9a69ed26e8 = []byte{ - // 4563 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7c, 0xcd, 0x6f, 0x1c, 0x47, - 0x76, 0xb8, 0x7a, 0x3e, 0xc8, 0x99, 0x37, 0x9f, 0x2c, 0x92, 0xd2, 0xec, 0xac, 0x24, 0xd3, 0x2d, - 0xcb, 0xe6, 0xd2, 0x36, 0xa9, 0xa5, 0x76, 0xbd, 0xda, 0xb5, 0x17, 0x5e, 0x89, 0x5c, 0xc9, 0x5c, - 0xcb, 0x34, 0x7f, 0x4d, 0x49, 0xfb, 0x83, 0xe1, 0xdd, 0xd9, 0xe6, 0x74, 0x71, 0xd8, 0x50, 0x7f, - 0x8c, 0xba, 0x7b, 0x48, 0xd3, 0x01, 0x72, 0xca, 0x25, 0x8b, 0x24, 0x48, 0x4e, 0xc9, 0x21, 0xc8, - 0x21, 0x41, 0x80, 0x4d, 0x90, 0xdc, 0x92, 0x5b, 0x0e, 0x39, 0x25, 0x01, 0x82, 0x7c, 0x5c, 0x82, - 0xfc, 0x03, 0xc9, 0x21, 0x40, 0x82, 0x20, 0x87, 0x45, 0xe0, 0x5b, 0x50, 0x5f, 0xdd, 0x5d, 0xdd, - 0x35, 0x9c, 0x21, 0x47, 0x5a, 0xdb, 0x41, 0x6e, 0xd3, 0xaf, 0xab, 0xea, 0xbd, 0x7a, 0xdf, 0xef, - 0x55, 0xd7, 0xc0, 0xc2, 0xb3, 0x11, 0x0e, 0x4e, 0x7b, 0x7d, 0xdf, 0x0f, 0xac, 0xf5, 0x61, 0xe0, - 0x47, 0x3e, 0x42, 0xae, 0xed, 0x1c, 0x8f, 0x42, 0xf6, 0xb4, 0x4e, 0xdf, 0x77, 0xeb, 0x7d, 0xdf, - 0x75, 0x7d, 0x8f, 0xc1, 0xba, 0xf5, 0xf4, 0x88, 0x6e, 0xd3, 0xf6, 0x22, 0x1c, 0x78, 0xa6, 0x23, - 0xde, 0x86, 0xfd, 0x23, 0xec, 0x9a, 0xfc, 0xa9, 0xea, 0x86, 0x03, 0xfe, 0xb3, 0x6d, 0x99, 0x91, - 0x99, 0x46, 0xa5, 0xff, 0x8a, 0x06, 0x97, 0xf7, 0x8f, 0xfc, 0x93, 0x2d, 0xdf, 0x71, 0x70, 0x3f, - 0xb2, 0x7d, 0x2f, 0x34, 0xf0, 0xb3, 0x11, 0x0e, 0x23, 0x74, 0x0b, 0x4a, 0x07, 0x66, 0x88, 0x3b, - 0xda, 0x8a, 0xb6, 0x5a, 0xdb, 0xbc, 0xba, 0x2e, 0x11, 0xc5, 0xa9, 0xf9, 0x20, 0x1c, 0xdc, 0x33, - 0x43, 0x6c, 0xd0, 0x91, 0x08, 0x41, 0xc9, 0x3a, 0xd8, 0xd9, 0xee, 0x14, 0x56, 0xb4, 0xd5, 0xa2, - 0x41, 0x7f, 0xa3, 0x57, 0xa0, 0xd1, 0x8f, 0xd7, 0xde, 0xd9, 0x0e, 0x3b, 0xc5, 0x95, 0xe2, 0x6a, - 0xd1, 0x90, 0x81, 0xfa, 0x4f, 0x0b, 0x70, 0x25, 0x47, 0x46, 0x38, 0xf4, 0xbd, 0x10, 0xa3, 0xdb, - 0x30, 0x17, 0x46, 0x66, 0x34, 0x0a, 0x39, 0x25, 0x5f, 0x55, 0x52, 0xb2, 0x4f, 0x87, 0x18, 0x7c, - 0x68, 0x1e, 0x6d, 0x41, 0x81, 0x16, 0x7d, 0x1d, 0x96, 0x6c, 0xef, 0x03, 0xec, 0xfa, 0xc1, 0x69, - 0x6f, 0x88, 0x83, 0x3e, 0xf6, 0x22, 0x73, 0x80, 0x05, 0x8d, 0x8b, 0xe2, 0xdd, 0x5e, 0xf2, 0x0a, - 0xbd, 0x05, 0x57, 0x98, 0xc0, 0x42, 0x1c, 0x1c, 0xdb, 0x7d, 0xdc, 0x33, 0x8f, 0x4d, 0xdb, 0x31, - 0x0f, 0x1c, 0xdc, 0x29, 0xad, 0x14, 0x57, 0x2b, 0xc6, 0x32, 0x7d, 0xbd, 0xcf, 0xde, 0xde, 0x15, - 0x2f, 0xd1, 0xd7, 0xa0, 0x1d, 0xe0, 0xc3, 0x00, 0x87, 0x47, 0xbd, 0x61, 0xe0, 0x0f, 0x02, 0x1c, - 0x86, 0x9d, 0x32, 0x45, 0xd3, 0xe2, 0xf0, 0x3d, 0x0e, 0xd6, 0xff, 0x50, 0x83, 0x65, 0xc2, 0x8c, - 0x3d, 0x33, 0x88, 0xec, 0x17, 0x20, 0x12, 0x1d, 0xea, 0x69, 0x36, 0x74, 0x8a, 0xf4, 0x9d, 0x04, - 0x23, 0x63, 0x86, 0x02, 0x3d, 0x61, 0x5f, 0x89, 0x92, 0x2a, 0xc1, 0xf4, 0x7f, 0xe0, 0xba, 0x93, - 0xa6, 0x73, 0x16, 0x99, 0x65, 0x71, 0x16, 0xf2, 0x38, 0x2f, 0x22, 0x31, 0x15, 0xe7, 0x4b, 0x6a, - 0xce, 0xff, 0x5d, 0x11, 0x96, 0x1f, 0xfa, 0xa6, 0x95, 0xa8, 0xe1, 0x2f, 0x9e, 0xf3, 0xdf, 0x85, - 0x39, 0x66, 0xbe, 0x9d, 0x12, 0xc5, 0x75, 0x53, 0xc6, 0xc5, 0x4d, 0x3b, 0xa1, 0x70, 0x9f, 0x02, - 0x0c, 0x3e, 0x09, 0xdd, 0x84, 0x66, 0x80, 0x87, 0x8e, 0xdd, 0x37, 0x7b, 0xde, 0xc8, 0x3d, 0xc0, - 0x41, 0xa7, 0xbc, 0xa2, 0xad, 0x96, 0x8d, 0x06, 0x87, 0xee, 0x52, 0x20, 0xfa, 0x09, 0x34, 0x0e, - 0x6d, 0xec, 0x58, 0x3d, 0xdb, 0xb3, 0xf0, 0x27, 0x3b, 0xdb, 0x9d, 0xb9, 0x95, 0xe2, 0x6a, 0x6d, - 0xf3, 0xed, 0xf5, 0xbc, 0xeb, 0x59, 0x57, 0x72, 0x64, 0xfd, 0x3e, 0x99, 0xbe, 0xc3, 0x66, 0x7f, - 0xdf, 0x8b, 0x82, 0x53, 0xa3, 0x7e, 0x98, 0x02, 0xa1, 0x0e, 0xcc, 0x73, 0xf6, 0x76, 0xe6, 0x57, - 0xb4, 0xd5, 0x8a, 0x21, 0x1e, 0xd1, 0x6b, 0xd0, 0x0a, 0x70, 0xe8, 0x8f, 0x82, 0x3e, 0xee, 0x0d, - 0x02, 0x7f, 0x34, 0x0c, 0x3b, 0x95, 0x95, 0xe2, 0x6a, 0xd5, 0x68, 0x0a, 0xf0, 0x03, 0x0a, 0xed, - 0xbe, 0x0b, 0x0b, 0x39, 0x2c, 0xa8, 0x0d, 0xc5, 0xa7, 0xf8, 0x94, 0x0a, 0xa2, 0x68, 0x90, 0x9f, - 0x68, 0x09, 0xca, 0xc7, 0xa6, 0x33, 0xc2, 0x9c, 0xd5, 0xec, 0xe1, 0x3b, 0x85, 0x3b, 0x9a, 0xfe, - 0xbb, 0x1a, 0x74, 0x0c, 0xec, 0x60, 0x33, 0xc4, 0x9f, 0xa7, 0x48, 0x2f, 0xc3, 0x9c, 0xe7, 0x5b, - 0x78, 0x67, 0x9b, 0x8a, 0xb4, 0x68, 0xf0, 0x27, 0xfd, 0x33, 0x0d, 0x96, 0x1e, 0xe0, 0x88, 0x98, - 0x81, 0x1d, 0x46, 0x76, 0x3f, 0xb6, 0xf3, 0xef, 0x42, 0x31, 0xc0, 0xcf, 0x38, 0x65, 0xaf, 0xcb, - 0x94, 0xc5, 0xbe, 0x5e, 0x35, 0xd3, 0x20, 0xf3, 0xd0, 0xcb, 0x50, 0xb7, 0x5c, 0xa7, 0xd7, 0x3f, - 0x32, 0x3d, 0x0f, 0x3b, 0xcc, 0x90, 0xaa, 0x46, 0xcd, 0x72, 0x9d, 0x2d, 0x0e, 0x42, 0xd7, 0x01, - 0x42, 0x3c, 0x70, 0xb1, 0x17, 0x25, 0x3e, 0x39, 0x05, 0x41, 0x6b, 0xb0, 0x70, 0x18, 0xf8, 0x6e, - 0x2f, 0x3c, 0x32, 0x03, 0xab, 0xe7, 0x60, 0xd3, 0xc2, 0x01, 0xa5, 0xbe, 0x62, 0xb4, 0xc8, 0x8b, - 0x7d, 0x02, 0x7f, 0x48, 0xc1, 0xe8, 0x36, 0x94, 0xc3, 0xbe, 0x3f, 0xc4, 0x54, 0xd3, 0x9a, 0x9b, - 0xd7, 0x54, 0x3a, 0xb4, 0x6d, 0x46, 0xe6, 0x3e, 0x19, 0x64, 0xb0, 0xb1, 0xfa, 0x7f, 0x71, 0x53, - 0xfb, 0x82, 0x3b, 0xb9, 0x94, 0x39, 0x96, 0x9f, 0x8f, 0x39, 0xce, 0x4d, 0x65, 0x8e, 0xf3, 0x67, - 0x9b, 0x63, 0x8e, 0x6b, 0xe7, 0x31, 0xc7, 0xca, 0x44, 0x73, 0xac, 0xbe, 0x18, 0x73, 0xfc, 0xcb, - 0xc4, 0x1c, 0xbf, 0xe8, 0x62, 0x4f, 0x4c, 0xb6, 0x2c, 0x99, 0xec, 0x1f, 0x69, 0xf0, 0x95, 0x07, - 0x38, 0x8a, 0xc9, 0x27, 0x16, 0x88, 0xbf, 0xa0, 0xf1, 0xf9, 0x4f, 0x35, 0xe8, 0xaa, 0x68, 0x9d, - 0x25, 0x46, 0x7f, 0x04, 0x97, 0x63, 0x1c, 0x3d, 0x0b, 0x87, 0xfd, 0xc0, 0x1e, 0x52, 0x31, 0x52, - 0x27, 0x53, 0xdb, 0xbc, 0xa1, 0xd2, 0xd8, 0x2c, 0x05, 0xcb, 0xf1, 0x12, 0xdb, 0xa9, 0x15, 0xf4, - 0x5f, 0xd7, 0x60, 0x99, 0x38, 0x35, 0xee, 0x85, 0xbc, 0x43, 0xff, 0xe2, 0x7c, 0x95, 0xfd, 0x5b, - 0x21, 0xe7, 0xdf, 0xa6, 0xe0, 0x31, 0xcd, 0x8d, 0xb3, 0xf4, 0xcc, 0xc2, 0xbb, 0x6f, 0x42, 0xd9, - 0xf6, 0x0e, 0x7d, 0xc1, 0xaa, 0x97, 0x54, 0xac, 0x4a, 0x23, 0x63, 0xa3, 0x75, 0x8f, 0x51, 0x91, - 0x38, 0xdc, 0x19, 0xd4, 0x2d, 0xbb, 0xed, 0x82, 0x62, 0xdb, 0xbf, 0xa6, 0xc1, 0x95, 0x1c, 0xc2, - 0x59, 0xf6, 0xfd, 0x0e, 0xcc, 0xd1, 0x30, 0x22, 0x36, 0xfe, 0x8a, 0x72, 0xe3, 0x29, 0x74, 0x0f, - 0xed, 0x30, 0x32, 0xf8, 0x1c, 0xdd, 0x87, 0x76, 0xf6, 0x1d, 0x09, 0x70, 0x3c, 0xb8, 0xf5, 0x3c, - 0xd3, 0x65, 0x0c, 0xa8, 0x1a, 0x35, 0x0e, 0xdb, 0x35, 0x5d, 0x8c, 0xbe, 0x02, 0x15, 0x62, 0xb2, - 0x3d, 0xdb, 0x12, 0xe2, 0x9f, 0xa7, 0x26, 0x6c, 0x85, 0xe8, 0x1a, 0x00, 0x7d, 0x65, 0x5a, 0x56, - 0xc0, 0x62, 0x5f, 0xd5, 0xa8, 0x12, 0xc8, 0x5d, 0x02, 0xd0, 0x7f, 0x47, 0x83, 0xeb, 0xfb, 0xa7, - 0x5e, 0x7f, 0x17, 0x9f, 0x6c, 0x05, 0xd8, 0x8c, 0x70, 0xe2, 0x6d, 0x5f, 0x28, 0xe3, 0xd1, 0x0a, - 0xd4, 0x52, 0xf6, 0xcb, 0x55, 0x32, 0x0d, 0xd2, 0x7f, 0x4b, 0x83, 0x3a, 0x71, 0xff, 0x1f, 0xe0, - 0xc8, 0x24, 0x2a, 0x82, 0xbe, 0x0d, 0x55, 0xc7, 0x37, 0xad, 0x5e, 0x74, 0x3a, 0x64, 0xd4, 0x34, - 0xb3, 0xd4, 0x24, 0x31, 0xe3, 0xd1, 0xe9, 0x10, 0x1b, 0x15, 0x87, 0xff, 0x9a, 0x8a, 0xa2, 0xac, - 0x97, 0x29, 0x2a, 0xbc, 0xcc, 0x5f, 0x95, 0xe1, 0xf2, 0x0f, 0xcd, 0xa8, 0x7f, 0xb4, 0xed, 0x8a, - 0xec, 0xe2, 0xe2, 0x6c, 0x4a, 0xdc, 0x6e, 0x21, 0xed, 0x76, 0x9f, 0x9b, 0x5b, 0x8f, 0x4d, 0xb0, - 0xac, 0x32, 0x41, 0x52, 0x1d, 0xaf, 0x3f, 0xe1, 0x5a, 0x94, 0x32, 0xc1, 0x54, 0x12, 0x30, 0x77, - 0x91, 0x24, 0x60, 0x0b, 0x1a, 0xf8, 0x93, 0xbe, 0x33, 0x22, 0xea, 0x48, 0xb1, 0xb3, 0xe8, 0x7e, - 0x5d, 0x81, 0x3d, 0x6d, 0xff, 0x75, 0x3e, 0x69, 0x87, 0xd3, 0xc0, 0x44, 0xed, 0xe2, 0xc8, 0xa4, - 0x21, 0xbc, 0xb6, 0xb9, 0x32, 0x4e, 0xd4, 0x42, 0x3f, 0x98, 0xb8, 0xc9, 0x13, 0xba, 0x0a, 0x55, - 0x9e, 0x72, 0xec, 0x6c, 0x77, 0xaa, 0x94, 0x7d, 0x09, 0x00, 0x99, 0xd0, 0xe0, 0xce, 0x91, 0x53, - 0x08, 0x94, 0xc2, 0x77, 0x54, 0x08, 0xd4, 0xc2, 0x4e, 0x53, 0x1e, 0xf2, 0x04, 0x24, 0x4c, 0x81, - 0x48, 0x45, 0xee, 0x1f, 0x1e, 0x3a, 0xb6, 0x87, 0x77, 0x99, 0x84, 0x6b, 0x94, 0x08, 0x19, 0x48, - 0xd2, 0x94, 0x63, 0x1c, 0x84, 0xb6, 0xef, 0x75, 0xea, 0xf4, 0xbd, 0x78, 0xec, 0xf6, 0x60, 0x21, - 0x87, 0x42, 0x91, 0x7d, 0x7c, 0x23, 0x9d, 0x7d, 0x4c, 0xe6, 0x71, 0x2a, 0x3b, 0xf9, 0x99, 0x06, - 0xcb, 0x8f, 0xbd, 0x70, 0x74, 0x10, 0xef, 0xed, 0xf3, 0xd1, 0xe3, 0xac, 0x73, 0x2b, 0xe5, 0x9c, - 0x1b, 0xb1, 0xb9, 0x16, 0xdf, 0x05, 0x11, 0x37, 0x75, 0x05, 0x57, 0xa1, 0x1a, 0xc7, 0x37, 0xce, - 0x90, 0x04, 0x90, 0xf5, 0x2d, 0x85, 0x9c, 0x6f, 0x99, 0x8a, 0x34, 0x91, 0xad, 0x94, 0x52, 0xd9, - 0xca, 0x35, 0x80, 0x43, 0x67, 0x14, 0x1e, 0xf5, 0x22, 0xdb, 0xc5, 0x3c, 0x5b, 0xaa, 0x52, 0xc8, - 0x23, 0xdb, 0xc5, 0xe8, 0x2e, 0xd4, 0x0f, 0x6c, 0xcf, 0xf1, 0x07, 0xbd, 0xa1, 0x19, 0x1d, 0x85, - 0xbc, 0xce, 0x54, 0x89, 0x85, 0xe6, 0x96, 0xf7, 0xe8, 0x58, 0xa3, 0xc6, 0xe6, 0xec, 0x91, 0x29, - 0xe8, 0x3a, 0xd4, 0xbc, 0x91, 0xdb, 0xf3, 0x0f, 0x7b, 0x81, 0x7f, 0x12, 0xd2, 0x6a, 0xb2, 0x68, - 0x54, 0xbd, 0x91, 0xfb, 0xe1, 0xa1, 0xe1, 0x9f, 0x90, 0xf8, 0x52, 0x25, 0x91, 0x26, 0x74, 0xfc, - 0x01, 0xab, 0x24, 0x27, 0xaf, 0x9f, 0x4c, 0x20, 0xb3, 0x2d, 0xec, 0x44, 0x26, 0x9d, 0x5d, 0x9d, - 0x6e, 0x76, 0x3c, 0x01, 0xbd, 0x0a, 0xcd, 0xbe, 0xef, 0x0e, 0x4d, 0xca, 0xa1, 0xfb, 0x81, 0xef, - 0x52, 0xcb, 0x29, 0x1a, 0x19, 0x28, 0xda, 0x82, 0x1a, 0x4d, 0xed, 0xb9, 0x79, 0xd5, 0x28, 0x1e, - 0x5d, 0x65, 0x5e, 0xa9, 0x14, 0x9b, 0x28, 0x28, 0xd8, 0xe2, 0x67, 0x48, 0x34, 0x43, 0x58, 0x69, - 0x68, 0x7f, 0x8a, 0xb9, 0x85, 0xd4, 0x38, 0x6c, 0xdf, 0xfe, 0x14, 0x93, 0x7a, 0xc3, 0xf6, 0x42, - 0x1c, 0x44, 0xa2, 0xfa, 0xeb, 0x34, 0xa8, 0xfa, 0x34, 0x18, 0x94, 0x2b, 0x36, 0xda, 0x86, 0x66, - 0x18, 0x99, 0x41, 0xd4, 0x1b, 0xfa, 0x21, 0x55, 0x80, 0x4e, 0x93, 0xea, 0x76, 0xa6, 0x76, 0x73, - 0xc3, 0x01, 0x51, 0xec, 0x3d, 0x3e, 0xc8, 0x68, 0xd0, 0x49, 0xe2, 0x11, 0x7d, 0x0f, 0xea, 0xd8, - 0xb3, 0x92, 0x35, 0x5a, 0xd3, 0xac, 0x51, 0xc3, 0x9e, 0x25, 0x1e, 0xf4, 0xff, 0x2c, 0x40, 0x53, - 0xde, 0x30, 0xf1, 0x00, 0xac, 0x70, 0x11, 0x5a, 0x2c, 0x1e, 0xc9, 0xf6, 0xb1, 0x67, 0x1e, 0x38, - 0x98, 0x55, 0x49, 0x54, 0x89, 0x2b, 0x64, 0x3d, 0x02, 0xa3, 0x0b, 0x10, 0x65, 0x64, 0x6c, 0xa6, - 0x96, 0x53, 0xa4, 0x5b, 0xaf, 0x52, 0x08, 0x4d, 0x0a, 0x3a, 0x30, 0x2f, 0x0a, 0x2c, 0xa6, 0xc2, - 0xe2, 0x91, 0xbc, 0x39, 0x18, 0xd9, 0x14, 0x2b, 0x53, 0x61, 0xf1, 0x88, 0xb6, 0xa1, 0xce, 0x96, - 0x1c, 0x9a, 0x81, 0xe9, 0x0a, 0x05, 0x7e, 0x59, 0xe9, 0x04, 0xde, 0xc7, 0xa7, 0x4f, 0x88, 0x3f, - 0xd9, 0x33, 0xed, 0xc0, 0x60, 0x02, 0xdf, 0xa3, 0xb3, 0xd0, 0x2a, 0xb4, 0xd9, 0x2a, 0x87, 0xb6, - 0x83, 0xb9, 0x29, 0xcc, 0xb3, 0x2a, 0x8b, 0xc2, 0xef, 0xdb, 0x0e, 0x66, 0xda, 0x1e, 0x6f, 0x81, - 0x8a, 0xb8, 0xc2, 0x94, 0x9d, 0x42, 0xa8, 0x80, 0x6f, 0x40, 0x83, 0xbd, 0x16, 0x6e, 0x92, 0xf9, - 0x72, 0x46, 0xe3, 0x13, 0x06, 0xa3, 0xc9, 0xcf, 0xc8, 0x65, 0xe6, 0x02, 0x6c, 0x3b, 0xde, 0xc8, - 0x25, 0xc6, 0xa2, 0xff, 0x6d, 0x09, 0x16, 0x89, 0xcf, 0xe0, 0xee, 0x63, 0x86, 0x58, 0x7d, 0x0d, - 0xc0, 0x0a, 0xa3, 0x9e, 0xe4, 0xe7, 0xaa, 0x56, 0x18, 0x71, 0x4f, 0xfe, 0x6d, 0x11, 0x6a, 0x8b, - 0xe3, 0x0b, 0x83, 0x8c, 0x0f, 0xcb, 0x87, 0xdb, 0x0b, 0xb5, 0xc0, 0x6e, 0x40, 0x83, 0x97, 0xb3, - 0x52, 0x09, 0x57, 0x67, 0xc0, 0x5d, 0xb5, 0x27, 0x9e, 0x53, 0xb6, 0xe2, 0x52, 0x21, 0x77, 0x7e, - 0xb6, 0x90, 0x5b, 0xc9, 0x86, 0xdc, 0xfb, 0xd0, 0xa2, 0x6e, 0x24, 0x36, 0x1f, 0xe1, 0x7d, 0x26, - 0xd8, 0x4f, 0x93, 0xce, 0x12, 0x8f, 0x61, 0x3a, 0x62, 0x82, 0x14, 0x31, 0x09, 0x1f, 0x3c, 0x8c, - 0xad, 0x5e, 0x14, 0x98, 0x5e, 0x78, 0x88, 0x03, 0x1a, 0x71, 0x2b, 0x46, 0x9d, 0x00, 0x1f, 0x71, - 0x18, 0x7a, 0x07, 0x80, 0xee, 0x91, 0x75, 0x70, 0xea, 0xe3, 0x3b, 0x38, 0x54, 0x69, 0x68, 0x07, - 0x87, 0x32, 0x85, 0xfe, 0xd4, 0xff, 0xbe, 0x00, 0x97, 0x79, 0x45, 0x3f, 0xbb, 0x42, 0x8d, 0x0b, - 0x9a, 0x22, 0xea, 0x14, 0xcf, 0xa8, 0x91, 0x4b, 0x53, 0x24, 0x84, 0x65, 0x45, 0x42, 0x28, 0xd7, - 0x89, 0x73, 0xb9, 0x3a, 0x31, 0xee, 0x6d, 0xcd, 0x4f, 0xdf, 0xdb, 0x42, 0x4b, 0x50, 0xa6, 0xc5, - 0x0b, 0x15, 0x7a, 0xd5, 0x60, 0x0f, 0x53, 0x89, 0x43, 0xff, 0xed, 0x02, 0x34, 0xf6, 0xb1, 0x19, - 0xf4, 0x8f, 0x04, 0x1f, 0xdf, 0x4a, 0xf7, 0x02, 0x5f, 0x19, 0xd3, 0x0b, 0x94, 0xa6, 0x7c, 0x69, - 0x9a, 0x80, 0x04, 0x41, 0xe4, 0x47, 0x66, 0x4c, 0x65, 0xcf, 0x1b, 0xb9, 0xbc, 0x41, 0xd6, 0xa2, - 0x2f, 0x38, 0xa9, 0xbb, 0x23, 0x57, 0xff, 0x77, 0x0d, 0xea, 0xff, 0x8f, 0x2c, 0x23, 0x18, 0x73, - 0x27, 0xcd, 0x98, 0x57, 0xc7, 0x30, 0xc6, 0xc0, 0x51, 0x60, 0xe3, 0x63, 0xfc, 0xa5, 0xeb, 0x8f, - 0xfe, 0xb5, 0x06, 0x5d, 0x52, 0x85, 0x1a, 0xcc, 0x61, 0xcc, 0x6e, 0x5d, 0x37, 0xa0, 0x71, 0x2c, - 0xe5, 0x95, 0x05, 0xaa, 0x9c, 0xf5, 0xe3, 0x74, 0xd5, 0x6c, 0x40, 0x5b, 0xb4, 0x2b, 0xf9, 0x66, - 0x85, 0xff, 0x7e, 0x4d, 0x45, 0x75, 0x86, 0x38, 0xea, 0xff, 0x5a, 0x81, 0x0c, 0xd4, 0x7f, 0x43, - 0x83, 0x45, 0xc5, 0x40, 0x74, 0x05, 0xe6, 0x79, 0x85, 0xce, 0x03, 0x3d, 0xb3, 0x77, 0x8b, 0x88, - 0x27, 0xe9, 0x31, 0xd9, 0x56, 0x3e, 0x59, 0xb5, 0xd0, 0x4b, 0x50, 0x8b, 0xeb, 0x15, 0x2b, 0x27, - 0x1f, 0x2b, 0x44, 0x5d, 0xa8, 0x70, 0x37, 0x28, 0x0a, 0xc1, 0xf8, 0x59, 0x7f, 0x0a, 0xe8, 0x01, - 0x4e, 0x82, 0xce, 0x2c, 0x1c, 0x4d, 0xfc, 0x4d, 0x42, 0x68, 0xda, 0x09, 0x59, 0xfa, 0xbf, 0x68, - 0xb0, 0x28, 0x61, 0x9b, 0xa5, 0x93, 0x92, 0x04, 0xc6, 0xc2, 0x45, 0x02, 0xa3, 0xd4, 0x2d, 0x28, - 0x9e, 0xab, 0x5b, 0x70, 0x1d, 0x20, 0xe6, 0xbf, 0xe0, 0x68, 0x0a, 0xa2, 0xff, 0x85, 0x06, 0x97, - 0xdf, 0x33, 0x3d, 0xcb, 0x3f, 0x3c, 0x9c, 0x5d, 0x55, 0xb7, 0x40, 0x2a, 0x1d, 0xa7, 0xed, 0x97, - 0xc9, 0xf5, 0xe6, 0xeb, 0xb0, 0x10, 0xb0, 0xc8, 0x64, 0xc9, 0xba, 0x5c, 0x34, 0xda, 0xe2, 0x45, - 0xac, 0xa3, 0x7f, 0x52, 0x00, 0x44, 0x76, 0x7d, 0xcf, 0x74, 0x4c, 0xaf, 0x8f, 0x2f, 0x4e, 0xfa, - 0x4d, 0x68, 0x4a, 0xb9, 0x47, 0x7c, 0xf0, 0x9c, 0x4e, 0x3e, 0x42, 0xf4, 0x3e, 0x34, 0x0f, 0x18, - 0xaa, 0x5e, 0x80, 0xcd, 0xd0, 0xf7, 0xb8, 0x38, 0x94, 0xad, 0xb1, 0x47, 0x81, 0x3d, 0x18, 0xe0, - 0x60, 0xcb, 0xf7, 0x2c, 0x9e, 0x86, 0x1f, 0x08, 0x32, 0xc9, 0x54, 0x62, 0x0c, 0x49, 0x22, 0x16, - 0x0b, 0x27, 0xce, 0xc4, 0x28, 0x2b, 0x42, 0x6c, 0x3a, 0x09, 0x23, 0x92, 0x68, 0xd8, 0x66, 0x2f, - 0xf6, 0xc7, 0x77, 0x46, 0x15, 0x89, 0x91, 0xfe, 0x67, 0x1a, 0xa0, 0xb8, 0x4a, 0xa6, 0xfd, 0x00, - 0x6a, 0xd1, 0xd9, 0xa9, 0x9a, 0x22, 0x28, 0x5f, 0x85, 0xaa, 0x25, 0x66, 0x72, 0x17, 0x94, 0x00, - 0x68, 0x8c, 0xa4, 0x44, 0xf7, 0x88, 0xe6, 0x61, 0x4b, 0x54, 0xa1, 0x0c, 0xf8, 0x90, 0xc2, 0xe4, - 0xbc, 0xaa, 0x94, 0xcd, 0xab, 0xd2, 0x8d, 0xbf, 0xb2, 0xd4, 0xf8, 0xd3, 0x7f, 0x56, 0x80, 0x36, - 0x0d, 0x21, 0x5b, 0x49, 0x8b, 0x67, 0x2a, 0xa2, 0x6f, 0x40, 0x83, 0x7f, 0xa5, 0x21, 0x11, 0x5e, - 0x7f, 0x96, 0x5a, 0x0c, 0xdd, 0x82, 0x25, 0x36, 0x28, 0xc0, 0xe1, 0xc8, 0x49, 0x0a, 0x30, 0x56, - 0x85, 0xa0, 0x67, 0x2c, 0x76, 0x91, 0x57, 0x62, 0xc6, 0x63, 0xb8, 0x3c, 0x70, 0xfc, 0x03, 0xd3, - 0xe9, 0xc9, 0xe2, 0x61, 0x32, 0x9c, 0x42, 0xe3, 0x97, 0xd8, 0xf4, 0xfd, 0xb4, 0x0c, 0x43, 0x74, - 0x0f, 0x1a, 0x21, 0xc6, 0x4f, 0x93, 0xba, 0xac, 0x3c, 0x4d, 0x5d, 0x56, 0x27, 0x73, 0xe2, 0xc2, - 0xec, 0xf7, 0x34, 0x68, 0x65, 0xda, 0xf6, 0xd9, 0x1e, 0x82, 0x96, 0xef, 0x21, 0xdc, 0x81, 0x32, - 0xf1, 0x54, 0x2c, 0xb6, 0x34, 0xd5, 0xf5, 0xad, 0xbc, 0xaa, 0xc1, 0x26, 0xa0, 0x0d, 0x58, 0x54, - 0x9c, 0xeb, 0x73, 0xf1, 0xa3, 0xfc, 0xb1, 0xbe, 0xfe, 0xf3, 0x12, 0xd4, 0x52, 0xac, 0x98, 0xd0, - 0xfe, 0x78, 0x2e, 0xed, 0xd7, 0x71, 0xe7, 0xb8, 0x44, 0xe5, 0x5c, 0xec, 0xb2, 0x82, 0x8d, 0x57, - 0x8f, 0x2e, 0x76, 0x69, 0xb9, 0x96, 0xae, 0xc4, 0xe6, 0xa4, 0x4a, 0x2c, 0x53, 0xab, 0xce, 0x9f, - 0x51, 0xab, 0x56, 0xe4, 0x5a, 0x55, 0x32, 0xa1, 0x6a, 0xd6, 0x84, 0xa6, 0xed, 0x48, 0xdc, 0x82, - 0xc5, 0x3e, 0x6b, 0x6f, 0xdf, 0x3b, 0xdd, 0x8a, 0x5f, 0xf1, 0xa4, 0x54, 0xf5, 0x0a, 0xdd, 0x4f, - 0x9a, 0x84, 0x4c, 0xca, 0xac, 0x5a, 0x50, 0x97, 0xc2, 0x5c, 0x36, 0x4c, 0xc8, 0xc2, 0x33, 0xd3, - 0xa7, 0x6c, 0x2f, 0xa4, 0x71, 0xa1, 0x5e, 0xc8, 0x4b, 0x50, 0x13, 0x99, 0x0a, 0xb1, 0xf4, 0x26, - 0x73, 0x7a, 0xc2, 0x0d, 0x58, 0xa1, 0xe4, 0x07, 0x5a, 0xf2, 0x01, 0x40, 0xb6, 0x91, 0xd0, 0xce, - 0x37, 0x12, 0xae, 0xc0, 0xbc, 0x1d, 0xf6, 0x0e, 0xcd, 0xa7, 0xb8, 0xb3, 0x40, 0xdf, 0xce, 0xd9, - 0xe1, 0x7d, 0xf3, 0x29, 0xd6, 0xff, 0xb1, 0x08, 0xcd, 0x24, 0xc0, 0x4e, 0xed, 0x41, 0xa6, 0xf9, - 0xb6, 0x65, 0x17, 0xda, 0x49, 0xde, 0x43, 0x39, 0x7c, 0x66, 0xf1, 0x9c, 0x3d, 0x55, 0x6b, 0x0d, - 0x33, 0xf6, 0x2a, 0x85, 0xfb, 0xd2, 0xb9, 0xc2, 0xfd, 0x8c, 0xa7, 0xde, 0xb7, 0x61, 0x39, 0x8e, - 0xbd, 0xd2, 0xb6, 0x59, 0x81, 0xb5, 0x24, 0x5e, 0xee, 0xa5, 0xb7, 0x3f, 0xc6, 0x05, 0xcc, 0x8f, - 0x73, 0x01, 0x59, 0x15, 0xa8, 0xe4, 0x54, 0x20, 0x7f, 0xf8, 0x5e, 0x55, 0x1c, 0xbe, 0xeb, 0x8f, - 0x61, 0x91, 0xf6, 0x7d, 0xc3, 0x7e, 0x60, 0x1f, 0xe0, 0xb8, 0x04, 0x98, 0x46, 0xac, 0x5d, 0xa8, - 0x64, 0xaa, 0x88, 0xf8, 0x59, 0xff, 0xa9, 0x06, 0x97, 0xf3, 0xeb, 0x52, 0x8d, 0x49, 0x1c, 0x89, - 0x26, 0x39, 0x92, 0xff, 0x0f, 0x8b, 0xa9, 0x8c, 0x52, 0x5a, 0x79, 0x4c, 0x06, 0xae, 0x20, 0xdc, - 0x40, 0xc9, 0x1a, 0x02, 0xa6, 0xff, 0x5c, 0x8b, 0xdb, 0xe7, 0x04, 0x36, 0xa0, 0x87, 0x0a, 0x24, - 0xae, 0xf9, 0x9e, 0x63, 0x7b, 0x71, 0xa7, 0x84, 0xef, 0x91, 0x01, 0x79, 0xa7, 0xe4, 0x3d, 0x68, - 0xf1, 0x41, 0x71, 0x78, 0x9a, 0x32, 0x21, 0x6b, 0xb2, 0x79, 0x71, 0x60, 0xba, 0x09, 0x4d, 0xde, - 0xed, 0x17, 0xf8, 0x8a, 0xaa, 0x33, 0x80, 0x1f, 0x40, 0x5b, 0x0c, 0x3b, 0x6f, 0x40, 0x6c, 0xf1, - 0x89, 0x71, 0x62, 0xf7, 0xab, 0x1a, 0x74, 0xe4, 0xf0, 0x98, 0xda, 0xfe, 0xf9, 0xd3, 0xbb, 0xb7, - 0xe5, 0x23, 0xdc, 0x9b, 0x67, 0xd0, 0x93, 0xe0, 0x11, 0x07, 0xb9, 0xbf, 0x59, 0xa0, 0xe7, 0xf1, - 0xa4, 0xd4, 0xdb, 0xb6, 0xc3, 0x28, 0xb0, 0x0f, 0x46, 0xb3, 0x1d, 0x2a, 0x9a, 0x50, 0xeb, 0x1f, - 0xe1, 0xfe, 0xd3, 0xa1, 0x6f, 0x27, 0x52, 0x79, 0x57, 0x45, 0xd3, 0x78, 0xb4, 0xeb, 0x5b, 0xc9, - 0x0a, 0xec, 0xd8, 0x26, 0xbd, 0x66, 0xf7, 0x47, 0xd0, 0xce, 0x0e, 0x48, 0x1f, 0xba, 0x54, 0xd9, - 0xa1, 0xcb, 0x6d, 0xf9, 0xd0, 0x65, 0x42, 0xa6, 0x91, 0x3a, 0x73, 0xf9, 0xf3, 0x02, 0x7c, 0x55, - 0x49, 0xdb, 0x2c, 0x55, 0xd2, 0xb8, 0x3e, 0xd2, 0x3d, 0xa8, 0x64, 0x8a, 0xda, 0x57, 0xcf, 0x90, - 0x1f, 0xef, 0xa5, 0xb2, 0x9e, 0x5e, 0x98, 0xe4, 0x56, 0x89, 0xc1, 0x97, 0xc6, 0xaf, 0xc1, 0xed, - 0x4e, 0x5a, 0x43, 0xcc, 0x43, 0x77, 0xa1, 0xce, 0x1a, 0x06, 0xbd, 0x63, 0x1b, 0x9f, 0x88, 0xb3, - 0xc8, 0xeb, 0x4a, 0xd7, 0x4c, 0xc7, 0x3d, 0xb1, 0xf1, 0x89, 0x51, 0x73, 0xe2, 0xdf, 0xa1, 0xfe, - 0x1f, 0x45, 0x80, 0xe4, 0x1d, 0xa9, 0xce, 0x12, 0x9b, 0xe7, 0x46, 0x9c, 0x82, 0x90, 0x5c, 0x42, - 0xce, 0x5c, 0xc5, 0x23, 0x32, 0x92, 0x23, 0x05, 0xcb, 0x0e, 0x23, 0xce, 0x97, 0x8d, 0xb3, 0x69, - 0x11, 0x2c, 0x22, 0x22, 0xe3, 0x3a, 0x13, 0x26, 0x10, 0xf4, 0x26, 0xa0, 0x41, 0xe0, 0x9f, 0xd8, - 0xde, 0x20, 0x5d, 0x6f, 0xb0, 0xb2, 0x64, 0x81, 0xbf, 0x49, 0x15, 0x1c, 0x3f, 0x86, 0x76, 0x66, - 0xb8, 0x60, 0xc9, 0xed, 0x09, 0x64, 0x3c, 0x90, 0xd6, 0xe2, 0xea, 0xdb, 0x92, 0x31, 0x84, 0xdd, - 0x1e, 0xb4, 0xb3, 0xf4, 0x2a, 0xce, 0x0d, 0xbf, 0x29, 0xab, 0xf0, 0x59, 0x9e, 0x86, 0x2c, 0x93, - 0x52, 0xe2, 0xae, 0x09, 0x4b, 0x2a, 0x4a, 0x14, 0x48, 0x2e, 0x6c, 0x27, 0xef, 0xc6, 0xc9, 0x2e, - 0xe5, 0xf0, 0xb8, 0xf8, 0x91, 0xea, 0x05, 0x17, 0xa4, 0x5e, 0xb0, 0xfe, 0x37, 0x1a, 0xa0, 0xbc, - 0x62, 0xa3, 0x26, 0x14, 0xe2, 0x45, 0x0a, 0x3b, 0xdb, 0x19, 0x45, 0x2a, 0xe4, 0x14, 0xe9, 0x2a, - 0x54, 0xe3, 0x78, 0xce, 0x9d, 0x77, 0x02, 0x48, 0xab, 0x59, 0x49, 0x56, 0xb3, 0x14, 0x61, 0x65, - 0xb9, 0x49, 0x7d, 0x0b, 0x96, 0x1c, 0x33, 0x8c, 0x7a, 0xac, 0x17, 0x1e, 0xd9, 0x2e, 0x0e, 0x23, - 0xd3, 0x1d, 0xd2, 0x64, 0xb9, 0x64, 0x20, 0xf2, 0x6e, 0x9b, 0xbc, 0x7a, 0x24, 0xde, 0xe8, 0x47, - 0x80, 0xf2, 0xe6, 0x95, 0xc6, 0xad, 0xc9, 0xb8, 0x27, 0xed, 0x29, 0x45, 0x5b, 0x51, 0x66, 0xda, - 0x1f, 0x14, 0x01, 0x25, 0x39, 0x4e, 0x7c, 0xd2, 0x3a, 0x4d, 0x62, 0xb0, 0x01, 0x8b, 0xf9, 0x0c, - 0x48, 0xa4, 0x7d, 0x28, 0x97, 0xff, 0xa8, 0x72, 0x95, 0xa2, 0xea, 0x43, 0xc1, 0xb7, 0x62, 0x87, - 0xc8, 0x12, 0xba, 0xeb, 0x63, 0x5b, 0xf5, 0xb2, 0x4f, 0xfc, 0x51, 0xf6, 0x03, 0x43, 0x66, 0x61, - 0x77, 0x94, 0xce, 0x2b, 0xb7, 0xe5, 0x89, 0x5f, 0x17, 0x4a, 0xa9, 0xe6, 0xdc, 0x79, 0x52, 0xcd, - 0xd9, 0xbf, 0x2a, 0xfc, 0xe7, 0x02, 0x2c, 0xc4, 0x8c, 0x3c, 0x97, 0x90, 0x26, 0x1f, 0x8a, 0xbf, - 0x60, 0xa9, 0x7c, 0xac, 0x96, 0xca, 0xb7, 0xce, 0x4c, 0xf7, 0xa7, 0x15, 0xca, 0xec, 0x9c, 0xfd, - 0x14, 0xe6, 0x79, 0xe3, 0x36, 0xe7, 0x28, 0xa6, 0x29, 0xa8, 0x97, 0xa0, 0x4c, 0xfc, 0x92, 0xe8, - 0xba, 0xb1, 0x07, 0xc6, 0xd2, 0xf4, 0xe7, 0xa6, 0xdc, 0x57, 0x34, 0xa4, 0xaf, 0x4d, 0xf5, 0x7f, - 0xd3, 0x00, 0xf6, 0x4f, 0xbd, 0xfe, 0x5d, 0x66, 0xa4, 0xb7, 0xa0, 0x34, 0xe9, 0x1b, 0x27, 0x32, - 0x9a, 0xea, 0x16, 0x1d, 0x39, 0x85, 0x70, 0xa5, 0x96, 0x41, 0x31, 0xdb, 0x32, 0x18, 0x57, 0xec, - 0x8f, 0x77, 0x65, 0xdf, 0x82, 0x12, 0x49, 0xf4, 0xf8, 0x37, 0x42, 0x53, 0x1d, 0x78, 0xd2, 0x09, - 0xfa, 0x67, 0x05, 0xb8, 0x42, 0xa8, 0x7f, 0x3e, 0x59, 0xe1, 0x34, 0xa2, 0x49, 0x79, 0xcb, 0xa2, - 0xec, 0x2d, 0xef, 0xc0, 0x3c, 0x2b, 0xf7, 0x45, 0x7e, 0x73, 0x7d, 0x1c, 0xaf, 0x99, 0x64, 0x0c, - 0x31, 0x7c, 0xd6, 0x9a, 0x51, 0x3a, 0x6c, 0x9d, 0x9b, 0xed, 0xb0, 0x75, 0x3e, 0xdb, 0x14, 0x4c, - 0x09, 0xad, 0x22, 0xfb, 0xf8, 0xc7, 0xd0, 0x30, 0xd2, 0x8a, 0x87, 0x10, 0x94, 0x52, 0xdf, 0x14, - 0xd2, 0xdf, 0xb4, 0xcc, 0x33, 0x87, 0x66, 0xdf, 0x8e, 0x4e, 0x29, 0x3b, 0xcb, 0x46, 0xfc, 0xac, - 0xd6, 0x72, 0xfd, 0xbf, 0x35, 0xb8, 0x2c, 0x0e, 0xf5, 0xb8, 0x0d, 0x5d, 0x5c, 0xa2, 0x9b, 0xb0, - 0xcc, 0x0d, 0x26, 0x63, 0x39, 0x2c, 0x99, 0x5b, 0x64, 0x30, 0x79, 0x1b, 0x9b, 0xb0, 0x1c, 0x99, - 0xc1, 0x00, 0x47, 0xd9, 0x39, 0x4c, 0xde, 0x8b, 0xec, 0xa5, 0x3c, 0x67, 0x9a, 0x43, 0xd5, 0x97, - 0xd8, 0xc7, 0x38, 0x9c, 0xb5, 0xdc, 0x04, 0xc0, 0x1b, 0xb9, 0x7c, 0x97, 0xfa, 0x09, 0x5c, 0x65, - 0x5f, 0xf5, 0x1e, 0xc8, 0x14, 0xcd, 0xd4, 0x53, 0x57, 0xee, 0x3b, 0xe3, 0x31, 0x7e, 0x5f, 0x83, - 0x6b, 0x63, 0x30, 0xcf, 0x52, 0x4d, 0x3c, 0x54, 0x62, 0x1f, 0x53, 0xfb, 0x49, 0x78, 0xa9, 0x86, - 0x66, 0x88, 0xfc, 0xac, 0x04, 0x0b, 0xb9, 0x41, 0xe7, 0xd6, 0xb9, 0x37, 0x00, 0x11, 0x21, 0xc4, - 0x57, 0xcf, 0x68, 0x39, 0xcd, 0x43, 0x53, 0xdb, 0x1b, 0xb9, 0xf1, 0xb5, 0x33, 0x52, 0x51, 0x23, - 0x9b, 0x8d, 0x66, 0x1d, 0xf5, 0x58, 0x72, 0xa5, 0xf1, 0x37, 0x0c, 0x72, 0x04, 0xae, 0xef, 0x8e, - 0x5c, 0xd6, 0x7c, 0xe7, 0x52, 0x66, 0xe1, 0x86, 0xa0, 0x92, 0xc0, 0xe8, 0x10, 0x16, 0xe8, 0xa7, - 0x5a, 0xa3, 0x68, 0xe0, 0x93, 0x84, 0x9e, 0xd2, 0xc5, 0x82, 0xda, 0x77, 0xa6, 0xc6, 0xf4, 0x21, - 0x9f, 0x4d, 0x88, 0xe7, 0x39, 0xbd, 0x27, 0x43, 0x05, 0x1e, 0xdb, 0xeb, 0xfb, 0x6e, 0x8c, 0x67, - 0xee, 0x9c, 0x78, 0x76, 0xf8, 0x6c, 0x19, 0x4f, 0x1a, 0xda, 0xdd, 0x82, 0x65, 0xe5, 0xd6, 0x27, - 0x85, 0xd1, 0x72, 0xba, 0x3e, 0xb8, 0x07, 0x4b, 0xaa, 0x5d, 0x5d, 0x60, 0x8d, 0x1c, 0xc5, 0xe7, - 0x59, 0x43, 0xff, 0xe3, 0x02, 0x34, 0xb6, 0xb1, 0x83, 0x23, 0xfc, 0x62, 0xcf, 0x3c, 0x73, 0x07, - 0xb8, 0xc5, 0xfc, 0x01, 0x6e, 0xee, 0x34, 0xba, 0xa4, 0x38, 0x8d, 0xbe, 0x16, 0x1f, 0xc2, 0x93, - 0x55, 0xca, 0x72, 0x84, 0xb6, 0xd0, 0xdb, 0x50, 0x1f, 0x06, 0xb6, 0x6b, 0x06, 0xa7, 0xbd, 0xa7, - 0xf8, 0x34, 0xe4, 0x41, 0xa3, 0xa3, 0x0c, 0x3b, 0x3b, 0xdb, 0xa1, 0x51, 0xe3, 0xa3, 0xdf, 0xc7, - 0xa7, 0xf4, 0x80, 0x3f, 0x2e, 0x36, 0xd8, 0xa7, 0x58, 0x25, 0x23, 0x05, 0x59, 0x5b, 0x81, 0x6a, - 0xfc, 0xc5, 0x0b, 0xaa, 0x40, 0xe9, 0xfe, 0xc8, 0x71, 0xda, 0x97, 0x50, 0x15, 0xca, 0xb4, 0x1c, - 0x69, 0x6b, 0x6b, 0xdf, 0x83, 0x6a, 0x7c, 0x6a, 0x8f, 0x6a, 0x30, 0xff, 0xd8, 0x7b, 0xdf, 0xf3, - 0x4f, 0xbc, 0xf6, 0x25, 0x34, 0x0f, 0xc5, 0xbb, 0x8e, 0xd3, 0xd6, 0x50, 0x03, 0xaa, 0xfb, 0x51, - 0x80, 0x4d, 0x22, 0xb3, 0x76, 0x01, 0x35, 0x01, 0xde, 0xb3, 0xc3, 0xc8, 0x0f, 0xec, 0xbe, 0xe9, - 0xb4, 0x8b, 0x6b, 0x9f, 0x42, 0x53, 0x6e, 0xe2, 0xa2, 0x3a, 0x54, 0x76, 0xfd, 0xe8, 0xfb, 0x9f, - 0xd8, 0x61, 0xd4, 0xbe, 0x44, 0xc6, 0xef, 0xfa, 0xd1, 0x5e, 0x80, 0x43, 0xec, 0x45, 0x6d, 0x0d, - 0x01, 0xcc, 0x7d, 0xe8, 0x6d, 0xdb, 0xe1, 0xd3, 0x76, 0x01, 0x2d, 0xf2, 0xf3, 0x19, 0xd3, 0xd9, - 0xe1, 0x9d, 0xd1, 0x76, 0x91, 0x4c, 0x8f, 0x9f, 0x4a, 0xa8, 0x0d, 0xf5, 0x78, 0xc8, 0x83, 0xbd, - 0xc7, 0xed, 0x32, 0xa1, 0x9e, 0xfd, 0x9c, 0x5b, 0xb3, 0xa0, 0x9d, 0x3d, 0x57, 0x24, 0x6b, 0xb2, - 0x4d, 0xc4, 0xa0, 0xf6, 0x25, 0xb2, 0x33, 0x7e, 0xb0, 0xdb, 0xd6, 0x50, 0x0b, 0x6a, 0xa9, 0x63, - 0xd2, 0x76, 0x81, 0x00, 0x1e, 0x04, 0xc3, 0x3e, 0x57, 0x28, 0x46, 0x02, 0xd1, 0xce, 0x6d, 0xc2, - 0x89, 0xd2, 0xda, 0x3d, 0xa8, 0x88, 0x94, 0x9f, 0x0c, 0xe5, 0x2c, 0x22, 0x8f, 0xed, 0x4b, 0x68, - 0x01, 0x1a, 0xd2, 0x5d, 0xa6, 0xb6, 0x86, 0x10, 0x34, 0xe5, 0xdb, 0x86, 0xed, 0xc2, 0xda, 0x26, - 0x40, 0x92, 0x3a, 0x13, 0x72, 0x76, 0xbc, 0x63, 0xd3, 0xb1, 0x2d, 0x46, 0x1b, 0x79, 0x45, 0xb8, - 0x4b, 0xb9, 0xc3, 0x0c, 0xb5, 0x5d, 0x58, 0x5b, 0x83, 0x8a, 0x48, 0x07, 0x09, 0xdc, 0xc0, 0xae, - 0x7f, 0x8c, 0x99, 0x64, 0xf6, 0x31, 0x61, 0x65, 0x15, 0xca, 0x77, 0x5d, 0xec, 0x59, 0xed, 0xc2, - 0xe6, 0xbf, 0x2e, 0x02, 0xb0, 0x53, 0x41, 0xdf, 0x0f, 0x2c, 0xe4, 0xd0, 0xaf, 0x03, 0xb6, 0x7c, - 0x77, 0xe8, 0x7b, 0xe2, 0xc8, 0x22, 0x44, 0xeb, 0x99, 0x52, 0x9d, 0x3d, 0xe4, 0x07, 0x72, 0x46, - 0x74, 0x5f, 0x51, 0x8e, 0xcf, 0x0c, 0xd6, 0x2f, 0x21, 0x97, 0x62, 0x23, 0xc5, 0xed, 0x23, 0xbb, - 0xff, 0x34, 0x3e, 0x4a, 0x1c, 0x7f, 0xe5, 0x2f, 0x33, 0x54, 0xe0, 0xbb, 0xa1, 0xc4, 0xb7, 0x1f, - 0x05, 0xb6, 0x37, 0x10, 0xf1, 0x4f, 0xbf, 0x84, 0x9e, 0x65, 0x2e, 0x1c, 0x0a, 0x84, 0x9b, 0xd3, - 0xdc, 0x31, 0xbc, 0x18, 0x4a, 0x07, 0x5a, 0x99, 0x9b, 0xdd, 0x68, 0x4d, 0x7d, 0x01, 0x44, 0x75, - 0x0b, 0xbd, 0xfb, 0xfa, 0x54, 0x63, 0x63, 0x6c, 0x36, 0x34, 0xe5, 0x2b, 0xc9, 0xe8, 0x6b, 0xe3, - 0x16, 0xc8, 0x5d, 0x41, 0xeb, 0xae, 0x4d, 0x33, 0x34, 0x46, 0xf5, 0x11, 0xd3, 0xd5, 0x49, 0xa8, - 0x94, 0xd7, 0xf5, 0xba, 0x67, 0xa5, 0x1e, 0xfa, 0x25, 0xf4, 0x13, 0x92, 0x25, 0x64, 0x2e, 0xca, - 0xa1, 0x37, 0xd4, 0x91, 0x4d, 0x7d, 0x9f, 0x6e, 0x12, 0x86, 0x8f, 0xb2, 0x96, 0x36, 0x9e, 0xfa, - 0xdc, 0xd5, 0xd9, 0xe9, 0xa9, 0x4f, 0x2d, 0x7f, 0x16, 0xf5, 0xe7, 0xc6, 0xe0, 0xb0, 0x82, 0x49, - 0x71, 0x45, 0x27, 0xab, 0xca, 0x49, 0xbd, 0x32, 0xfe, 0x3e, 0xcf, 0x24, 0x6c, 0x23, 0x6a, 0xa4, - 0xd9, 0xe3, 0xf0, 0x37, 0xc7, 0x34, 0xda, 0xd5, 0x77, 0x03, 0xbb, 0xeb, 0xd3, 0x0e, 0x4f, 0xeb, - 0xb2, 0x7c, 0xfd, 0x4c, 0x2d, 0x22, 0xe5, 0x95, 0x39, 0xb5, 0x2e, 0xab, 0x6f, 0xb3, 0xe9, 0x97, - 0xd0, 0x23, 0xc9, 0xaf, 0xa3, 0x57, 0xc7, 0xa9, 0x82, 0xfc, 0x7d, 0xcc, 0x24, 0xbe, 0xfd, 0x12, - 0x20, 0x66, 0xa9, 0xde, 0xa1, 0x3d, 0x18, 0x05, 0x26, 0x53, 0xe3, 0x71, 0xce, 0x2d, 0x3f, 0x54, - 0xa0, 0xf9, 0xfa, 0x39, 0x66, 0xc4, 0x5b, 0xea, 0x01, 0x3c, 0xc0, 0xd1, 0x07, 0x38, 0x0a, 0xec, - 0x7e, 0x98, 0xdd, 0x51, 0xe2, 0xbf, 0xf9, 0x00, 0x81, 0xea, 0xb5, 0x89, 0xe3, 0x62, 0x04, 0x07, - 0x50, 0x7b, 0x40, 0x2a, 0x28, 0x9a, 0x15, 0x86, 0x68, 0xec, 0x4c, 0x31, 0x42, 0xa0, 0x58, 0x9d, - 0x3c, 0x30, 0xed, 0x3c, 0x33, 0x57, 0xf1, 0xd0, 0x58, 0xc1, 0xe6, 0x2f, 0x08, 0xaa, 0x9d, 0xe7, - 0x98, 0xbb, 0x7d, 0x6c, 0x47, 0xf4, 0xb0, 0xe7, 0x3d, 0x6c, 0x3a, 0xd1, 0xd1, 0x98, 0x1d, 0xa5, - 0x46, 0x9c, 0xbd, 0x23, 0x69, 0x60, 0x8c, 0x03, 0xc3, 0x22, 0xb3, 0x42, 0xb9, 0xf4, 0xdc, 0x50, - 0x2f, 0x91, 0x1f, 0x39, 0xa5, 0xea, 0x99, 0xb0, 0xb0, 0x1d, 0xf8, 0x43, 0x19, 0xc9, 0x9b, 0x4a, - 0x24, 0xb9, 0x71, 0x53, 0xa2, 0xf8, 0x21, 0xd4, 0x45, 0x85, 0x4f, 0x6b, 0x12, 0x35, 0x17, 0xd2, - 0x43, 0xa6, 0x5c, 0xf8, 0x63, 0x68, 0x65, 0x5a, 0x07, 0x6a, 0xa1, 0xab, 0xfb, 0x0b, 0x93, 0x56, - 0x3f, 0x01, 0x44, 0xef, 0x57, 0x4a, 0x77, 0xbb, 0xc7, 0xe4, 0x37, 0xf9, 0x81, 0x02, 0xc9, 0xc6, - 0xd4, 0xe3, 0x63, 0xc9, 0xff, 0x32, 0x2c, 0x2b, 0xcb, 0xf3, 0xac, 0x43, 0xe0, 0x1f, 0xc4, 0x9e, - 0xd1, 0x43, 0xc8, 0x3a, 0x84, 0x33, 0x67, 0x08, 0xfc, 0x9b, 0xff, 0xd4, 0x82, 0x2a, 0xcd, 0xf3, - 0xa8, 0xb4, 0xfe, 0x2f, 0xcd, 0x7b, 0xbe, 0x69, 0xde, 0xc7, 0xd0, 0xca, 0x5c, 0x0c, 0x54, 0x2b, - 0xad, 0xfa, 0xf6, 0xe0, 0x14, 0xd9, 0x8a, 0x7c, 0x35, 0x4f, 0x1d, 0x0a, 0x95, 0xd7, 0xf7, 0x26, - 0xad, 0xfd, 0x84, 0xdd, 0xa9, 0x8d, 0xbf, 0x52, 0x78, 0x6d, 0x6c, 0xf3, 0x5e, 0xfe, 0xb0, 0xf5, - 0xf3, 0xcf, 0x82, 0xbe, 0xdc, 0x19, 0xe8, 0xc7, 0xd0, 0xca, 0x5c, 0x1d, 0x51, 0x6b, 0x8c, 0xfa, - 0x7e, 0xc9, 0xa4, 0xd5, 0x7f, 0x81, 0xc9, 0x93, 0x05, 0x8b, 0x8a, 0x2f, 0xf5, 0xd1, 0xfa, 0xb8, - 0x44, 0x54, 0xfd, 0x49, 0xff, 0xe4, 0x0d, 0x35, 0x24, 0x33, 0xcd, 0xc6, 0x9b, 0x84, 0xc8, 0xec, - 0x9f, 0xc2, 0x74, 0xdf, 0x98, 0xee, 0x1f, 0x64, 0xe2, 0x0d, 0xed, 0xc3, 0x1c, 0xbb, 0x50, 0x82, - 0x5e, 0x56, 0x1f, 0x62, 0xa4, 0x2e, 0x9b, 0x74, 0x27, 0x5d, 0x49, 0x09, 0x47, 0x4e, 0x14, 0xd2, - 0x45, 0xcb, 0xd4, 0xfb, 0x22, 0x65, 0x57, 0x3f, 0x7d, 0xb3, 0xa3, 0x3b, 0xf9, 0x32, 0x87, 0x58, - 0xf4, 0x7f, 0x77, 0x86, 0xf9, 0x09, 0xbd, 0x3a, 0x90, 0xfd, 0x38, 0x06, 0xad, 0x9f, 0xef, 0x0b, - 0x9f, 0xee, 0xc6, 0xd4, 0xe3, 0x63, 0xcc, 0x3f, 0x86, 0x76, 0xf6, 0x40, 0x0a, 0xbd, 0x3e, 0x4e, - 0x9f, 0x55, 0x38, 0x27, 0x28, 0xf3, 0x0f, 0x60, 0x8e, 0x75, 0x22, 0xd5, 0x1a, 0x26, 0x75, 0x29, - 0x27, 0xac, 0x75, 0xef, 0x1b, 0x1f, 0x6d, 0x0e, 0xec, 0xe8, 0x68, 0x74, 0x40, 0xde, 0x6c, 0xb0, - 0xa1, 0x6f, 0xda, 0x3e, 0xff, 0xb5, 0x21, 0x64, 0xb9, 0x41, 0x67, 0x6f, 0x50, 0x04, 0xc3, 0x83, - 0x83, 0x39, 0xfa, 0x78, 0xfb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xae, 0xfb, 0x09, 0x88, 0x7f, - 0x4f, 0x00, 0x00, + // 4599 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3c, 0x4b, 0x6f, 0x24, 0xc7, + 0x79, 0xdb, 0xf3, 0xe2, 0xcc, 0x37, 0x4f, 0x16, 0xc9, 0xdd, 0xf1, 0x78, 0x77, 0x45, 0xf5, 0xea, + 0x41, 0x53, 0x12, 0x29, 0x73, 0x6d, 0x59, 0xb6, 0x64, 0xc8, 0xbb, 0xa4, 0x76, 0x45, 0x4b, 0xa2, + 0x98, 0xe6, 0xae, 0x1c, 0x08, 0xb2, 0xc7, 0xcd, 0xe9, 0xe2, 0xb0, 0xb1, 0xfd, 0x98, 0xed, 0xea, + 0x21, 0x45, 0x05, 0xc8, 0x29, 0x97, 0x18, 0x71, 0x90, 0x9c, 0x92, 0x43, 0x90, 0x43, 0x82, 0x00, + 0x4e, 0x90, 0xdc, 0x92, 0x5b, 0x0e, 0x39, 0x25, 0x01, 0x82, 0x3c, 0x2e, 0x41, 0xfe, 0x40, 0x72, + 0x08, 0x90, 0x20, 0xc8, 0xc1, 0x08, 0x74, 0x0b, 0xea, 0xd1, 0x8f, 0xea, 0xae, 0xe1, 0x0c, 0x39, + 0xbb, 0x96, 0x14, 0xe4, 0x36, 0xfd, 0xd5, 0xe3, 0xfb, 0xaa, 0xbe, 0xf7, 0x57, 0x55, 0x03, 0x8b, + 0x8f, 0xc7, 0x38, 0x38, 0xeb, 0x0f, 0x7c, 0x3f, 0xb0, 0x36, 0x46, 0x81, 0x1f, 0xfa, 0x08, 0xb9, + 0xb6, 0x73, 0x32, 0x26, 0xfc, 0x6b, 0x83, 0xb5, 0xf7, 0x1a, 0x03, 0xdf, 0x75, 0x7d, 0x8f, 0xc3, + 0x7a, 0x8d, 0x74, 0x8f, 0x5e, 0xcb, 0xf6, 0x42, 0x1c, 0x78, 0xa6, 0x13, 0xb5, 0x92, 0xc1, 0x31, + 0x76, 0x4d, 0xf1, 0x55, 0x73, 0xc9, 0x50, 0xfc, 0xec, 0x58, 0x66, 0x68, 0xa6, 0x51, 0xf5, 0x16, + 0x6d, 0xcf, 0xc2, 0x9f, 0xa4, 0x41, 0xfa, 0xaf, 0x69, 0x70, 0xf5, 0xe0, 0xd8, 0x3f, 0xdd, 0xf6, + 0x1d, 0x07, 0x0f, 0x42, 0xdb, 0xf7, 0x88, 0x81, 0x1f, 0x8f, 0x31, 0x09, 0xd1, 0xab, 0x50, 0x3a, + 0x34, 0x09, 0xee, 0x6a, 0xab, 0xda, 0x5a, 0x7d, 0xeb, 0xfa, 0x86, 0x44, 0xa7, 0x20, 0xf0, 0x7d, + 0x32, 0xbc, 0x6b, 0x12, 0x6c, 0xb0, 0x9e, 0x08, 0x41, 0xc9, 0x3a, 0xdc, 0xdd, 0xe9, 0x16, 0x56, + 0xb5, 0xb5, 0xa2, 0xc1, 0x7e, 0xa3, 0xe7, 0xa0, 0x39, 0x88, 0xe7, 0xde, 0xdd, 0x21, 0xdd, 0xe2, + 0x6a, 0x71, 0xad, 0x68, 0xc8, 0x40, 0xfd, 0x27, 0x05, 0xb8, 0x96, 0x23, 0x83, 0x8c, 0x7c, 0x8f, + 0x60, 0x74, 0x1b, 0x2a, 0x24, 0x34, 0xc3, 0x31, 0x11, 0x94, 0x7c, 0x55, 0x49, 0xc9, 0x01, 0xeb, + 0x62, 0x88, 0xae, 0x79, 0xb4, 0x05, 0x05, 0x5a, 0xf4, 0x75, 0x58, 0xb6, 0xbd, 0xf7, 0xb1, 0xeb, + 0x07, 0x67, 0xfd, 0x11, 0x0e, 0x06, 0xd8, 0x0b, 0xcd, 0x21, 0x8e, 0x68, 0x5c, 0x8a, 0xda, 0xf6, + 0x93, 0x26, 0xf4, 0x1a, 0x5c, 0xe3, 0x3c, 0x24, 0x38, 0x38, 0xb1, 0x07, 0xb8, 0x6f, 0x9e, 0x98, + 0xb6, 0x63, 0x1e, 0x3a, 0xb8, 0x5b, 0x5a, 0x2d, 0xae, 0x55, 0x8d, 0x15, 0xd6, 0x7c, 0xc0, 0x5b, + 0xef, 0x44, 0x8d, 0xe8, 0x6b, 0xd0, 0x09, 0xf0, 0x51, 0x80, 0xc9, 0x71, 0x7f, 0x14, 0xf8, 0xc3, + 0x00, 0x13, 0xd2, 0x2d, 0x33, 0x34, 0x6d, 0x01, 0xdf, 0x17, 0x60, 0xfd, 0x8f, 0x34, 0x58, 0xa1, + 0x9b, 0xb1, 0x6f, 0x06, 0xa1, 0xfd, 0x14, 0x58, 0xa2, 0x43, 0x23, 0xbd, 0x0d, 0xdd, 0x22, 0x6b, + 0x93, 0x60, 0xb4, 0xcf, 0x28, 0x42, 0x4f, 0xb7, 0xaf, 0xc4, 0x48, 0x95, 0x60, 0xfa, 0x3f, 0x0a, + 0xd9, 0x49, 0xd3, 0x39, 0x0f, 0xcf, 0xb2, 0x38, 0x0b, 0x79, 0x9c, 0x97, 0xe1, 0x98, 0x6a, 0xe7, + 0x4b, 0xea, 0x9d, 0xff, 0xfb, 0x22, 0xac, 0xbc, 0xe7, 0x9b, 0x56, 0x22, 0x86, 0xbf, 0xf8, 0x9d, + 0xff, 0x2e, 0x54, 0xb8, 0x46, 0x77, 0x4b, 0x0c, 0xd7, 0xf3, 0x32, 0x2e, 0xa1, 0xed, 0x09, 0x85, + 0x07, 0x0c, 0x60, 0x88, 0x41, 0xe8, 0x79, 0x68, 0x05, 0x78, 0xe4, 0xd8, 0x03, 0xb3, 0xef, 0x8d, + 0xdd, 0x43, 0x1c, 0x74, 0xcb, 0xab, 0xda, 0x5a, 0xd9, 0x68, 0x0a, 0xe8, 0x1e, 0x03, 0xa2, 0x1f, + 0x43, 0xf3, 0xc8, 0xc6, 0x8e, 0xd5, 0x67, 0x26, 0x61, 0x77, 0xa7, 0x5b, 0x59, 0x2d, 0xae, 0xd5, + 0xb7, 0xde, 0xd8, 0xc8, 0x5b, 0xa3, 0x0d, 0xe5, 0x8e, 0x6c, 0xdc, 0xa3, 0xc3, 0x77, 0xf9, 0xe8, + 0xb7, 0xbd, 0x30, 0x38, 0x33, 0x1a, 0x47, 0x29, 0x10, 0xea, 0xc2, 0x82, 0xd8, 0xde, 0xee, 0xc2, + 0xaa, 0xb6, 0x56, 0x35, 0xa2, 0x4f, 0xf4, 0x22, 0xb4, 0x03, 0x4c, 0xfc, 0x71, 0x30, 0xc0, 0xfd, + 0x61, 0xe0, 0x8f, 0x47, 0xa4, 0x5b, 0x5d, 0x2d, 0xae, 0xd5, 0x8c, 0x56, 0x04, 0xbe, 0xcf, 0xa0, + 0xbd, 0xb7, 0x60, 0x31, 0x87, 0x05, 0x75, 0xa0, 0xf8, 0x08, 0x9f, 0x31, 0x46, 0x14, 0x0d, 0xfa, + 0x13, 0x2d, 0x43, 0xf9, 0xc4, 0x74, 0xc6, 0x58, 0x6c, 0x35, 0xff, 0xf8, 0x4e, 0xe1, 0x75, 0x4d, + 0xff, 0x3d, 0x0d, 0xba, 0x06, 0x76, 0xb0, 0x49, 0xf0, 0xe7, 0xc9, 0xd2, 0xab, 0x50, 0xf1, 0x7c, + 0x0b, 0xef, 0xee, 0x30, 0x96, 0x16, 0x0d, 0xf1, 0xa5, 0x7f, 0xa6, 0xc1, 0xf2, 0x7d, 0x1c, 0x52, + 0x35, 0xb0, 0x49, 0x68, 0x0f, 0x62, 0x3d, 0xff, 0x2e, 0x14, 0x03, 0xfc, 0x58, 0x50, 0xf6, 0x92, + 0x4c, 0x59, 0x6c, 0xfe, 0x55, 0x23, 0x0d, 0x3a, 0x0e, 0x3d, 0x0b, 0x0d, 0xcb, 0x75, 0xfa, 0x83, + 0x63, 0xd3, 0xf3, 0xb0, 0xc3, 0x15, 0xa9, 0x66, 0xd4, 0x2d, 0xd7, 0xd9, 0x16, 0x20, 0x74, 0x13, + 0x80, 0xe0, 0xa1, 0x8b, 0xbd, 0x30, 0xb1, 0xc9, 0x29, 0x08, 0x5a, 0x87, 0xc5, 0xa3, 0xc0, 0x77, + 0xfb, 0xe4, 0xd8, 0x0c, 0xac, 0xbe, 0x83, 0x4d, 0x0b, 0x07, 0x8c, 0xfa, 0xaa, 0xd1, 0xa6, 0x0d, + 0x07, 0x14, 0xfe, 0x1e, 0x03, 0xa3, 0xdb, 0x50, 0x26, 0x03, 0x7f, 0x84, 0x99, 0xa4, 0xb5, 0xb6, + 0x6e, 0xa8, 0x64, 0x68, 0xc7, 0x0c, 0xcd, 0x03, 0xda, 0xc9, 0xe0, 0x7d, 0xf5, 0xff, 0x16, 0xaa, + 0xf6, 0x05, 0x37, 0x72, 0x29, 0x75, 0x2c, 0x3f, 0x19, 0x75, 0xac, 0xcc, 0xa4, 0x8e, 0x0b, 0xe7, + 0xab, 0x63, 0x6e, 0xd7, 0x2e, 0xa2, 0x8e, 0xd5, 0xa9, 0xea, 0x58, 0x7b, 0x3a, 0xea, 0xf8, 0x57, + 0x89, 0x3a, 0x7e, 0xd1, 0xd9, 0x9e, 0xa8, 0x6c, 0x59, 0x52, 0xd9, 0x3f, 0xd6, 0xe0, 0x2b, 0xf7, + 0x71, 0x18, 0x93, 0x4f, 0x35, 0x10, 0x7f, 0x41, 0xfd, 0xf3, 0x9f, 0x69, 0xd0, 0x53, 0xd1, 0x3a, + 0x8f, 0x8f, 0xfe, 0x08, 0xae, 0xc6, 0x38, 0xfa, 0x16, 0x26, 0x83, 0xc0, 0x1e, 0x31, 0x36, 0x32, + 0x23, 0x53, 0xdf, 0xba, 0xa5, 0x92, 0xd8, 0x2c, 0x05, 0x2b, 0xf1, 0x14, 0x3b, 0xa9, 0x19, 0xf4, + 0x9f, 0x6a, 0xb0, 0x42, 0x8d, 0x9a, 0xb0, 0x42, 0xde, 0x91, 0x7f, 0xf9, 0x7d, 0x95, 0xed, 0x5b, + 0x21, 0x67, 0xdf, 0x66, 0xd8, 0x63, 0x16, 0x1b, 0x67, 0xe9, 0x99, 0x67, 0xef, 0xbe, 0x09, 0x65, + 0xdb, 0x3b, 0xf2, 0xa3, 0xad, 0x7a, 0x46, 0xb5, 0x55, 0x69, 0x64, 0xbc, 0xb7, 0xee, 0x71, 0x2a, + 0x12, 0x83, 0x3b, 0x87, 0xb8, 0x65, 0x97, 0x5d, 0x50, 0x2c, 0xfb, 0x37, 0x34, 0xb8, 0x96, 0x43, + 0x38, 0xcf, 0xba, 0xdf, 0x84, 0x0a, 0x73, 0x23, 0xd1, 0xc2, 0x9f, 0x53, 0x2e, 0x3c, 0x85, 0xee, + 0x3d, 0x9b, 0x84, 0x86, 0x18, 0xa3, 0xfb, 0xd0, 0xc9, 0xb6, 0x51, 0x07, 0x27, 0x9c, 0x5b, 0xdf, + 0x33, 0x5d, 0xbe, 0x01, 0x35, 0xa3, 0x2e, 0x60, 0x7b, 0xa6, 0x8b, 0xd1, 0x57, 0xa0, 0x4a, 0x55, + 0xb6, 0x6f, 0x5b, 0x11, 0xfb, 0x17, 0x98, 0x0a, 0x5b, 0x04, 0xdd, 0x00, 0x60, 0x4d, 0xa6, 0x65, + 0x05, 0xdc, 0xf7, 0xd5, 0x8c, 0x1a, 0x85, 0xdc, 0xa1, 0x00, 0xfd, 0x77, 0x35, 0xb8, 0x79, 0x70, + 0xe6, 0x0d, 0xf6, 0xf0, 0xe9, 0x76, 0x80, 0xcd, 0x10, 0x27, 0xd6, 0xf6, 0xa9, 0x6e, 0x3c, 0x5a, + 0x85, 0x7a, 0x4a, 0x7f, 0x85, 0x48, 0xa6, 0x41, 0xfa, 0x6f, 0x6b, 0xd0, 0xa0, 0xe6, 0xff, 0x7d, + 0x1c, 0x9a, 0x54, 0x44, 0xd0, 0xb7, 0xa1, 0xe6, 0xf8, 0xa6, 0xd5, 0x0f, 0xcf, 0x46, 0x9c, 0x9a, + 0x56, 0x96, 0x9a, 0xc4, 0x67, 0x3c, 0x38, 0x1b, 0x61, 0xa3, 0xea, 0x88, 0x5f, 0x33, 0x51, 0x94, + 0xb5, 0x32, 0x45, 0x85, 0x95, 0xf9, 0x69, 0x05, 0xae, 0xfe, 0xc0, 0x0c, 0x07, 0xc7, 0x3b, 0x6e, + 0x14, 0x5d, 0x5c, 0x7e, 0x9b, 0x12, 0xb3, 0x5b, 0x48, 0x9b, 0xdd, 0x27, 0x66, 0xd6, 0x63, 0x15, + 0x2c, 0xab, 0x54, 0x90, 0x26, 0xcc, 0x1b, 0x1f, 0x0a, 0x29, 0x4a, 0xa9, 0x60, 0x2a, 0x08, 0xa8, + 0x5c, 0x26, 0x08, 0xd8, 0x86, 0x26, 0xfe, 0x64, 0xe0, 0x8c, 0xa9, 0x38, 0x32, 0xec, 0xdc, 0xbb, + 0xdf, 0x54, 0x60, 0x4f, 0xeb, 0x7f, 0x43, 0x0c, 0xda, 0x15, 0x34, 0x70, 0x56, 0xbb, 0x38, 0x34, + 0x99, 0x0b, 0xaf, 0x6f, 0xad, 0x4e, 0x62, 0x75, 0x24, 0x1f, 0x9c, 0xdd, 0xf4, 0x0b, 0x5d, 0x87, + 0x9a, 0x08, 0x39, 0x76, 0x77, 0xba, 0x35, 0xb6, 0x7d, 0x09, 0x00, 0x99, 0xd0, 0x14, 0xc6, 0x51, + 0x50, 0x08, 0x8c, 0xc2, 0x37, 0x55, 0x08, 0xd4, 0xcc, 0x4e, 0x53, 0x4e, 0x44, 0x00, 0x42, 0x52, + 0x20, 0xf4, 0x36, 0xb4, 0x79, 0xf9, 0x81, 0x22, 0xe8, 0x3b, 0x36, 0x09, 0xbb, 0x75, 0x86, 0xe4, + 0x46, 0x36, 0xbe, 0xb5, 0xf0, 0x27, 0x1b, 0x3c, 0xc6, 0xa0, 0x4b, 0x68, 0xda, 0xd1, 0x4f, 0xa6, + 0xfa, 0xcf, 0x41, 0xd3, 0x3f, 0x3a, 0x72, 0x6c, 0x0f, 0xef, 0x71, 0x41, 0x69, 0xb0, 0xb5, 0xc8, + 0x40, 0x1a, 0xed, 0x9c, 0xe0, 0x80, 0xd8, 0xbe, 0xd7, 0x6d, 0xb2, 0xf6, 0xe8, 0xb3, 0xd7, 0x87, + 0xc5, 0x1c, 0xa5, 0x8a, 0x20, 0xe6, 0x1b, 0xe9, 0x20, 0x66, 0x3a, 0xab, 0x52, 0x41, 0xce, 0xcf, + 0x34, 0x58, 0x79, 0xe8, 0x91, 0xf1, 0x61, 0xbc, 0x45, 0x9f, 0x8f, 0x3a, 0x64, 0x6d, 0x64, 0x29, + 0x67, 0x23, 0xf5, 0xbf, 0x2e, 0x43, 0x5b, 0xac, 0x82, 0x4a, 0x0d, 0xb3, 0x28, 0xd7, 0xa1, 0x16, + 0xbb, 0x49, 0xb1, 0x21, 0x09, 0x20, 0x6b, 0xa2, 0x0a, 0x39, 0x13, 0x35, 0x13, 0x69, 0x51, 0xd0, + 0x53, 0x4a, 0x05, 0x3d, 0x37, 0x00, 0x8e, 0x9c, 0x31, 0x39, 0xee, 0x87, 0xb6, 0x8b, 0x45, 0xd0, + 0x55, 0x63, 0x90, 0x07, 0xb6, 0x8b, 0xd1, 0x1d, 0x68, 0x1c, 0xda, 0x9e, 0xe3, 0x0f, 0xfb, 0x23, + 0x33, 0x3c, 0x26, 0x22, 0x5d, 0x55, 0xb1, 0x85, 0x85, 0xa8, 0x77, 0x59, 0x5f, 0xa3, 0xce, 0xc7, + 0xec, 0xd3, 0x21, 0xe8, 0x26, 0xd4, 0xbd, 0xb1, 0xdb, 0xf7, 0x8f, 0xfa, 0x81, 0x7f, 0x4a, 0x58, + 0x52, 0x5a, 0x34, 0x6a, 0xde, 0xd8, 0xfd, 0xe0, 0xc8, 0xf0, 0x4f, 0xa9, 0x9b, 0xaa, 0x51, 0x87, + 0x45, 0x1c, 0x7f, 0xc8, 0x13, 0xd2, 0xe9, 0xf3, 0x27, 0x03, 0xe8, 0x68, 0x0b, 0x3b, 0xa1, 0xc9, + 0x46, 0xd7, 0x66, 0x1b, 0x1d, 0x0f, 0x40, 0x2f, 0x40, 0x6b, 0xe0, 0xbb, 0x23, 0x93, 0xed, 0xd0, + 0xbd, 0xc0, 0x77, 0x99, 0x02, 0x16, 0x8d, 0x0c, 0x14, 0x6d, 0x43, 0x3d, 0x51, 0x22, 0x22, 0x14, + 0x48, 0x57, 0x69, 0x69, 0x2a, 0x52, 0xa7, 0x02, 0x0a, 0xb1, 0x16, 0x11, 0x2a, 0x19, 0x91, 0xb2, + 0x13, 0xfb, 0x53, 0x2c, 0x34, 0xa8, 0x2e, 0x60, 0x07, 0xf6, 0xa7, 0x98, 0xa6, 0x2d, 0xb6, 0x47, + 0x70, 0x10, 0x46, 0x49, 0x24, 0x53, 0xa3, 0x1a, 0x55, 0x46, 0x0a, 0x15, 0x82, 0x8d, 0x76, 0xa0, + 0x45, 0x42, 0x33, 0x08, 0xfb, 0x23, 0x9f, 0x30, 0x01, 0xe8, 0xb6, 0x98, 0x6c, 0x67, 0x54, 0xda, + 0x25, 0x43, 0x2a, 0xd8, 0xfb, 0xa2, 0x93, 0xd1, 0x64, 0x83, 0xa2, 0x4f, 0xf4, 0x3d, 0x68, 0x60, + 0xcf, 0x4a, 0xe6, 0x68, 0xcf, 0x32, 0x47, 0x1d, 0x7b, 0x56, 0xf4, 0xa1, 0xff, 0x57, 0x01, 0x5a, + 0xf2, 0x82, 0xa9, 0x05, 0xe0, 0xf9, 0x4f, 0x24, 0xc5, 0xd1, 0x27, 0x5d, 0x3e, 0xf6, 0xcc, 0x43, + 0x07, 0xf3, 0x64, 0x8b, 0x09, 0x71, 0x95, 0xce, 0x47, 0x61, 0x6c, 0x02, 0x2a, 0x8c, 0x7c, 0x9b, + 0x99, 0xe6, 0x14, 0xd9, 0xd2, 0x6b, 0x0c, 0xc2, 0x62, 0x8b, 0x2e, 0x2c, 0x44, 0x79, 0x1a, 0x17, + 0xe1, 0xe8, 0x93, 0xb6, 0x1c, 0x8e, 0x6d, 0x86, 0x95, 0x8b, 0x70, 0xf4, 0x89, 0x76, 0xa0, 0xc1, + 0xa7, 0x1c, 0x99, 0x81, 0xe9, 0x46, 0x02, 0xfc, 0xac, 0xd2, 0x08, 0xbc, 0x8b, 0xcf, 0x3e, 0xa4, + 0xf6, 0x64, 0xdf, 0xb4, 0x03, 0x83, 0x33, 0x7c, 0x9f, 0x8d, 0x42, 0x6b, 0xd0, 0xe1, 0xb3, 0x1c, + 0xd9, 0x0e, 0x16, 0xaa, 0xb0, 0xc0, 0x93, 0x35, 0x06, 0xbf, 0x67, 0x3b, 0x98, 0x4b, 0x7b, 0xbc, + 0x04, 0xc6, 0xe2, 0x2a, 0x17, 0x76, 0x06, 0x61, 0x0c, 0xbe, 0x05, 0xdc, 0xae, 0xf6, 0x23, 0x33, + 0xc9, 0x5d, 0x02, 0xa7, 0xf1, 0x43, 0x0e, 0x63, 0x31, 0xd4, 0xd8, 0xe5, 0xea, 0x02, 0x7c, 0x39, + 0xde, 0xd8, 0xa5, 0xca, 0xa2, 0xff, 0x5d, 0x09, 0x96, 0xa8, 0xcd, 0x10, 0xe6, 0x63, 0x0e, 0x97, + 0x7f, 0x03, 0xc0, 0x22, 0x61, 0x5f, 0xb2, 0x73, 0x35, 0x8b, 0x84, 0xc2, 0x92, 0x7f, 0x3b, 0xf2, + 0xd8, 0xc5, 0xc9, 0xf9, 0x45, 0xc6, 0x86, 0xe5, 0xbd, 0xf6, 0xa5, 0x2a, 0x69, 0xb7, 0xa0, 0x29, + 0xb2, 0x62, 0x29, 0x13, 0x6c, 0x70, 0xe0, 0x9e, 0xda, 0x12, 0x57, 0x94, 0x15, 0xbd, 0x94, 0xe7, + 0x5e, 0x98, 0xcf, 0x73, 0x57, 0xb3, 0x9e, 0xfb, 0x1e, 0xb4, 0x99, 0x19, 0x89, 0xd5, 0x27, 0xb2, + 0x3e, 0x53, 0xf4, 0xa7, 0xc5, 0x46, 0x45, 0x9f, 0x24, 0xed, 0x31, 0x41, 0xf2, 0x98, 0x74, 0x1f, + 0x3c, 0x8c, 0xad, 0x7e, 0x18, 0x98, 0x1e, 0x39, 0xc2, 0x41, 0xb7, 0xce, 0x14, 0xa6, 0x41, 0x81, + 0x0f, 0x04, 0x0c, 0xbd, 0x09, 0xc0, 0xd6, 0xc8, 0x0b, 0x41, 0x8d, 0xc9, 0x85, 0x20, 0x26, 0x34, + 0xac, 0x10, 0xc4, 0x36, 0x85, 0xfd, 0xd4, 0xff, 0xa1, 0x00, 0x57, 0x45, 0x61, 0x60, 0x7e, 0x81, + 0x9a, 0xe4, 0x34, 0x23, 0xaf, 0x53, 0x3c, 0x27, 0xd5, 0x2e, 0xcd, 0x10, 0x57, 0x96, 0x15, 0x71, + 0xa5, 0x9c, 0x6e, 0x56, 0x72, 0xe9, 0x66, 0x5c, 0x22, 0x5b, 0x98, 0xbd, 0x44, 0x86, 0x96, 0xa1, + 0xcc, 0x72, 0x20, 0xc6, 0xf4, 0x9a, 0xc1, 0x3f, 0x66, 0x62, 0x87, 0xfe, 0x3b, 0x05, 0x68, 0x1e, + 0x60, 0x33, 0x18, 0x1c, 0x47, 0xfb, 0xf8, 0x5a, 0xba, 0xa4, 0xf8, 0xdc, 0x84, 0x92, 0xa2, 0x34, + 0xe4, 0x4b, 0x53, 0x4b, 0xa4, 0x08, 0x42, 0x3f, 0x34, 0x63, 0x2a, 0xfb, 0xde, 0xd8, 0x15, 0x75, + 0xb6, 0x36, 0x6b, 0x10, 0xa4, 0xee, 0x8d, 0x5d, 0xfd, 0x3f, 0x34, 0x68, 0xfc, 0x12, 0x9d, 0x26, + 0xda, 0x98, 0xd7, 0xd3, 0x1b, 0xf3, 0xc2, 0x84, 0x8d, 0x31, 0x70, 0x18, 0xd8, 0xf8, 0x04, 0x7f, + 0xe9, 0xca, 0xac, 0x7f, 0xa3, 0x41, 0x8f, 0x26, 0xb3, 0x06, 0x37, 0x18, 0xf3, 0x6b, 0xd7, 0x2d, + 0x68, 0x9e, 0x48, 0x71, 0x65, 0x81, 0x09, 0x67, 0xe3, 0x24, 0x9d, 0x7c, 0x1b, 0xd0, 0x89, 0xaa, + 0x9e, 0x62, 0xb1, 0x91, 0xfd, 0x7e, 0x51, 0x45, 0x75, 0x86, 0x38, 0x66, 0xff, 0xda, 0x81, 0x0c, + 0xd4, 0x7f, 0x53, 0x83, 0x25, 0x45, 0x47, 0x74, 0x0d, 0x16, 0x44, 0xa2, 0x2f, 0x1c, 0x3d, 0xd7, + 0x77, 0x8b, 0xb2, 0x27, 0x29, 0x55, 0xd9, 0x56, 0x3e, 0x58, 0xb5, 0xd0, 0x33, 0x50, 0x8f, 0xd3, + 0x1e, 0x2b, 0xc7, 0x1f, 0x8b, 0xa0, 0x1e, 0x54, 0x85, 0x19, 0x8c, 0xf2, 0xc9, 0xf8, 0x5b, 0x7f, + 0x04, 0xe8, 0x3e, 0x4e, 0x9c, 0xce, 0x3c, 0x3b, 0x9a, 0xd8, 0x9b, 0x84, 0xd0, 0xb4, 0x11, 0xb2, + 0xf4, 0x7f, 0xd5, 0x60, 0x49, 0xc2, 0x36, 0x4f, 0x41, 0x26, 0x71, 0x8c, 0x85, 0xcb, 0x38, 0x46, + 0xa9, 0xe8, 0x50, 0xbc, 0x50, 0xd1, 0xe1, 0x26, 0x40, 0xbc, 0xff, 0xd1, 0x8e, 0xa6, 0x20, 0xfa, + 0x5f, 0x6a, 0x70, 0xf5, 0x1d, 0xd3, 0xb3, 0xfc, 0xa3, 0xa3, 0xf9, 0x45, 0x75, 0x1b, 0xa4, 0x0c, + 0x74, 0xd6, 0xb2, 0x9b, 0x9c, 0xb6, 0xbe, 0x04, 0x8b, 0x01, 0xf7, 0x4c, 0x96, 0x2c, 0xcb, 0x45, + 0xa3, 0x13, 0x35, 0xc4, 0x32, 0xfa, 0xa7, 0x05, 0x40, 0x74, 0xd5, 0x77, 0x4d, 0xc7, 0xf4, 0x06, + 0xf8, 0xf2, 0xa4, 0x3f, 0x0f, 0x2d, 0x29, 0xf6, 0x88, 0xcf, 0xaf, 0xd3, 0xc1, 0x07, 0x41, 0xef, + 0x42, 0xeb, 0x90, 0xa3, 0xea, 0x07, 0xd8, 0x24, 0xbe, 0x27, 0xd8, 0xa1, 0xac, 0xb0, 0x3d, 0x08, + 0xec, 0xe1, 0x10, 0x07, 0xdb, 0xbe, 0x67, 0x89, 0x30, 0xfc, 0x30, 0x22, 0x93, 0x0e, 0xa5, 0xca, + 0x90, 0x04, 0x62, 0x31, 0x73, 0xe2, 0x48, 0x8c, 0x6d, 0x05, 0xc1, 0xa6, 0x93, 0x6c, 0x44, 0xe2, + 0x0d, 0x3b, 0xbc, 0xe1, 0x60, 0x72, 0x81, 0x55, 0x11, 0x18, 0xe9, 0x7f, 0xae, 0x01, 0x8a, 0xb3, + 0x64, 0x56, 0x56, 0x60, 0x1a, 0x9d, 0x1d, 0xaa, 0x29, 0x9c, 0xf2, 0x75, 0xa8, 0x59, 0xd1, 0x48, + 0x61, 0x82, 0x12, 0x00, 0xf3, 0x91, 0x8c, 0xe8, 0x3e, 0x95, 0x3c, 0x6c, 0x45, 0x59, 0x28, 0x07, + 0xbe, 0xc7, 0x60, 0x72, 0x5c, 0x55, 0xca, 0xc6, 0x55, 0xe9, 0xfa, 0x61, 0x59, 0xaa, 0x1f, 0xea, + 0x3f, 0x2b, 0x40, 0x87, 0xb9, 0x90, 0xed, 0xa4, 0x52, 0x34, 0x13, 0xd1, 0xb7, 0xa0, 0x29, 0xee, + 0x7f, 0x48, 0x84, 0x37, 0x1e, 0xa7, 0x26, 0x43, 0xaf, 0xc2, 0x32, 0xef, 0x14, 0x60, 0x32, 0x76, + 0x92, 0x04, 0x8c, 0x67, 0x21, 0xe8, 0x31, 0xf7, 0x5d, 0xb4, 0x29, 0x1a, 0xf1, 0x10, 0xae, 0x0e, + 0x1d, 0xff, 0xd0, 0x74, 0xfa, 0x32, 0x7b, 0x38, 0x0f, 0x67, 0x90, 0xf8, 0x65, 0x3e, 0xfc, 0x20, + 0xcd, 0x43, 0x82, 0xee, 0x42, 0x93, 0x60, 0xfc, 0x28, 0xc9, 0xcb, 0xca, 0xb3, 0xe4, 0x65, 0x0d, + 0x3a, 0x26, 0x4e, 0xcc, 0x7e, 0x5f, 0x83, 0x76, 0xa6, 0xfa, 0x9f, 0xad, 0x21, 0x68, 0xf9, 0x1a, + 0xc2, 0xeb, 0x50, 0xa6, 0x96, 0x8a, 0xfb, 0x96, 0x96, 0x3a, 0xbf, 0x95, 0x67, 0x35, 0xf8, 0x00, + 0xb4, 0x09, 0x4b, 0x8a, 0xeb, 0x01, 0x82, 0xfd, 0x28, 0x7f, 0x3b, 0x40, 0xff, 0x79, 0x09, 0xea, + 0xa9, 0xad, 0x98, 0x52, 0xfe, 0x78, 0x22, 0x55, 0xdc, 0x49, 0xc7, 0xc1, 0x54, 0xe4, 0x5c, 0xec, + 0xf2, 0x84, 0x4d, 0x64, 0x8f, 0x2e, 0x76, 0x59, 0xba, 0x96, 0xce, 0xc4, 0x2a, 0x52, 0x26, 0x96, + 0xc9, 0x55, 0x17, 0xce, 0xc9, 0x55, 0xab, 0x72, 0xae, 0x2a, 0xa9, 0x50, 0x2d, 0xab, 0x42, 0xb3, + 0x56, 0x24, 0x5e, 0x85, 0xa5, 0x01, 0xaf, 0x92, 0xdf, 0x3d, 0xdb, 0x8e, 0x9b, 0x44, 0x50, 0xaa, + 0x6a, 0x42, 0xf7, 0x92, 0x5a, 0x23, 0xe7, 0x32, 0xcf, 0x16, 0xd4, 0xa9, 0xb0, 0xe0, 0x0d, 0x67, + 0x72, 0x64, 0x99, 0xd9, 0x57, 0xb6, 0x16, 0xd2, 0xbc, 0x54, 0x2d, 0xe4, 0x19, 0xa8, 0x47, 0x91, + 0x0a, 0xd5, 0xf4, 0x16, 0x37, 0x7a, 0x91, 0x19, 0xb0, 0x88, 0x64, 0x07, 0xda, 0xf2, 0x39, 0x42, + 0xb6, 0x90, 0xd0, 0xc9, 0x17, 0x12, 0xae, 0xc1, 0x82, 0x4d, 0xfa, 0x47, 0xe6, 0x23, 0xdc, 0x5d, + 0x64, 0xad, 0x15, 0x9b, 0xdc, 0x33, 0x1f, 0x61, 0xfd, 0x9f, 0x8a, 0xd0, 0x4a, 0x1c, 0xec, 0xcc, + 0x16, 0x64, 0x96, 0x2b, 0x32, 0x7b, 0xd0, 0x49, 0xe2, 0x1e, 0xb6, 0xc3, 0xe7, 0x26, 0xcf, 0xd9, + 0xc3, 0xb9, 0xf6, 0x28, 0xa3, 0xaf, 0x92, 0xbb, 0x2f, 0x5d, 0xc8, 0xdd, 0xcf, 0x79, 0x78, 0x7e, + 0x1b, 0x56, 0x62, 0xdf, 0x2b, 0x2d, 0x9b, 0x27, 0x58, 0xcb, 0x51, 0xe3, 0x7e, 0x7a, 0xf9, 0x13, + 0x4c, 0xc0, 0xc2, 0x24, 0x13, 0x90, 0x15, 0x81, 0x6a, 0x4e, 0x04, 0xf2, 0x67, 0xf8, 0x35, 0xc5, + 0x19, 0xbe, 0xfe, 0x10, 0x96, 0x58, 0xdd, 0x97, 0x0c, 0x02, 0xfb, 0x10, 0xc7, 0x29, 0xc0, 0x2c, + 0x6c, 0xed, 0x41, 0x35, 0x93, 0x45, 0xc4, 0xdf, 0xfa, 0x4f, 0x34, 0xb8, 0x9a, 0x9f, 0x97, 0x49, + 0x4c, 0x62, 0x48, 0x34, 0xc9, 0x90, 0xfc, 0x32, 0x2c, 0xa5, 0x22, 0x4a, 0x69, 0xe6, 0x09, 0x11, + 0xb8, 0x82, 0x70, 0x03, 0x25, 0x73, 0x44, 0x30, 0xfd, 0xe7, 0x5a, 0x5c, 0x3e, 0xa7, 0xb0, 0x21, + 0x3b, 0x9b, 0xa0, 0x7e, 0xcd, 0xf7, 0x1c, 0xdb, 0x8b, 0x2b, 0x25, 0x62, 0x8d, 0x1c, 0x28, 0x2a, + 0x25, 0xef, 0x40, 0x5b, 0x74, 0x8a, 0xdd, 0xd3, 0x8c, 0x01, 0x59, 0x8b, 0x8f, 0x8b, 0x1d, 0xd3, + 0xf3, 0xd0, 0x12, 0xd5, 0xfe, 0x08, 0x5f, 0x51, 0x75, 0x06, 0xf0, 0x7d, 0xe8, 0x44, 0xdd, 0x2e, + 0xea, 0x10, 0xdb, 0x62, 0x60, 0x1c, 0xd8, 0xfd, 0xba, 0x06, 0x5d, 0xd9, 0x3d, 0xa6, 0x96, 0x7f, + 0xf1, 0xf0, 0xee, 0x0d, 0xf9, 0x24, 0xf8, 0xf9, 0x73, 0xe8, 0x49, 0xf0, 0x44, 0xe7, 0xc1, 0xbf, + 0x55, 0x60, 0xc7, 0xfa, 0x34, 0xd5, 0xdb, 0xb1, 0x49, 0x18, 0xd8, 0x87, 0xe3, 0xf9, 0xce, 0x26, + 0x4d, 0xa8, 0x0f, 0x8e, 0xf1, 0xe0, 0xd1, 0xc8, 0xb7, 0x13, 0xae, 0xbc, 0xa5, 0xa2, 0x69, 0x32, + 0xda, 0x8d, 0xed, 0x64, 0x06, 0x7e, 0xfa, 0x93, 0x9e, 0xb3, 0xf7, 0x43, 0xe8, 0x64, 0x3b, 0xa4, + 0x0f, 0x5d, 0x6a, 0xfc, 0xd0, 0xe5, 0xb6, 0x7c, 0xe8, 0x32, 0x25, 0xd2, 0x48, 0x9d, 0xb9, 0xfc, + 0x45, 0x01, 0xbe, 0xaa, 0xa4, 0x6d, 0x9e, 0x2c, 0x69, 0x52, 0x1d, 0xe9, 0x2e, 0x54, 0x33, 0x49, + 0xed, 0x0b, 0xe7, 0xf0, 0x4f, 0xd4, 0x52, 0x79, 0x4d, 0x8f, 0x24, 0xb1, 0x55, 0xa2, 0xf0, 0xa5, + 0xc9, 0x73, 0x08, 0xbd, 0x93, 0xe6, 0x88, 0xc6, 0xa1, 0x3b, 0xd0, 0xe0, 0x05, 0x83, 0xfe, 0x89, + 0x8d, 0x4f, 0xa3, 0x23, 0xcd, 0x9b, 0x4a, 0xd3, 0xcc, 0xfa, 0x7d, 0x68, 0xe3, 0x53, 0xa3, 0xee, + 0xc4, 0xbf, 0x89, 0xfe, 0x9f, 0x45, 0x80, 0xa4, 0x8d, 0x66, 0x67, 0x89, 0xce, 0x0b, 0x25, 0x4e, + 0x41, 0x68, 0x2c, 0x21, 0x47, 0xae, 0xd1, 0x27, 0x32, 0x92, 0x23, 0x05, 0xcb, 0x26, 0xa1, 0xd8, + 0x97, 0xcd, 0xf3, 0x69, 0x89, 0xb6, 0x88, 0xb2, 0x4c, 0xc8, 0x0c, 0x49, 0x20, 0xe8, 0x15, 0x40, + 0xc3, 0xc0, 0x3f, 0xb5, 0xbd, 0x61, 0x3a, 0xdf, 0xe0, 0x69, 0xc9, 0xa2, 0x68, 0x49, 0x25, 0x1c, + 0x3f, 0x82, 0x4e, 0xa6, 0x7b, 0xb4, 0x25, 0xb7, 0xa7, 0x90, 0x71, 0x5f, 0x9a, 0x4b, 0x88, 0x6f, + 0x5b, 0xc6, 0x40, 0x7a, 0x7d, 0xe8, 0x64, 0xe9, 0x55, 0x9c, 0x1b, 0x7e, 0x53, 0x16, 0xe1, 0xf3, + 0x2c, 0x0d, 0x9d, 0x26, 0x25, 0xc4, 0x3d, 0x13, 0x96, 0x55, 0x94, 0x28, 0x90, 0x5c, 0x5a, 0x4f, + 0xde, 0x8a, 0x83, 0x5d, 0xb6, 0xc3, 0x93, 0xfc, 0x47, 0xaa, 0x16, 0x5c, 0x90, 0x6a, 0xc1, 0xfa, + 0xdf, 0x6a, 0x80, 0xf2, 0x82, 0x8d, 0x5a, 0x50, 0x88, 0x27, 0x29, 0xec, 0xee, 0x64, 0x04, 0xa9, + 0x90, 0x13, 0xa4, 0xeb, 0x50, 0x8b, 0xfd, 0xb9, 0x30, 0xde, 0x09, 0x20, 0x2d, 0x66, 0x25, 0x59, + 0xcc, 0x52, 0x84, 0x95, 0xe5, 0x22, 0xf5, 0xab, 0xb0, 0xec, 0x98, 0x24, 0xec, 0xf3, 0x5a, 0x78, + 0x68, 0xbb, 0x98, 0x84, 0xa6, 0x3b, 0x62, 0xc1, 0x72, 0xc9, 0x40, 0xb4, 0x6d, 0x87, 0x36, 0x3d, + 0x88, 0x5a, 0xf4, 0x63, 0x40, 0x79, 0xf5, 0x4a, 0xe3, 0xd6, 0x64, 0xdc, 0xd3, 0xd6, 0x94, 0xa2, + 0xad, 0x28, 0x6f, 0xda, 0x1f, 0x16, 0x01, 0x25, 0x31, 0x4e, 0x7c, 0xd2, 0x3a, 0x4b, 0x60, 0xb0, + 0x09, 0x4b, 0xf9, 0x08, 0x28, 0x0a, 0xfb, 0x50, 0x2e, 0xfe, 0x51, 0xc5, 0x2a, 0x45, 0xd5, 0x7d, + 0xc3, 0xd7, 0x62, 0x83, 0xc8, 0x03, 0xba, 0x9b, 0x13, 0x4b, 0xf5, 0xb2, 0x4d, 0xfc, 0x61, 0xf6, + 0x9e, 0x22, 0xd7, 0xb0, 0xd7, 0x95, 0xc6, 0x2b, 0xb7, 0xe4, 0xa9, 0x97, 0x14, 0xa5, 0x50, 0xb3, + 0x72, 0x91, 0x50, 0x73, 0xfe, 0xcb, 0x89, 0xff, 0x52, 0x80, 0xc5, 0x78, 0x23, 0x2f, 0xc4, 0xa4, + 0xe9, 0x87, 0xe2, 0x4f, 0x99, 0x2b, 0x1f, 0xab, 0xb9, 0xf2, 0xad, 0x73, 0xc3, 0xfd, 0x59, 0x99, + 0x32, 0xff, 0xce, 0x7e, 0x0a, 0x0b, 0xa2, 0x70, 0x9b, 0x33, 0x14, 0xb3, 0x24, 0xd4, 0xcb, 0x50, + 0xa6, 0x76, 0x29, 0xaa, 0xba, 0xf1, 0x0f, 0xbe, 0xa5, 0xe9, 0x5b, 0xab, 0xc2, 0x56, 0x34, 0xa5, + 0x4b, 0xab, 0xfa, 0xbf, 0x6b, 0x00, 0x07, 0x67, 0xde, 0xe0, 0x0e, 0x57, 0xd2, 0x57, 0xa1, 0x34, + 0xed, 0xaa, 0x14, 0xed, 0xcd, 0x64, 0x8b, 0xf5, 0x9c, 0x81, 0xb9, 0x52, 0xc9, 0xa0, 0x98, 0x2d, + 0x19, 0x4c, 0x4a, 0xf6, 0x27, 0x9b, 0xb2, 0x6f, 0x41, 0x89, 0x06, 0x7a, 0xe2, 0xaa, 0xd1, 0x4c, + 0x07, 0x9e, 0x6c, 0x80, 0xfe, 0x59, 0x01, 0xae, 0x51, 0xea, 0x9f, 0x4c, 0x54, 0x38, 0x0b, 0x6b, + 0x52, 0xd6, 0xb2, 0x28, 0x5b, 0xcb, 0xd7, 0x61, 0x81, 0xa7, 0xfb, 0x51, 0x7c, 0x73, 0x73, 0xd2, + 0x5e, 0x73, 0xce, 0x18, 0x51, 0xf7, 0x79, 0x73, 0x46, 0xe9, 0xb0, 0xb5, 0x32, 0xdf, 0x61, 0xeb, + 0x42, 0xb6, 0x28, 0x98, 0x62, 0x5a, 0x55, 0xb6, 0xf1, 0x0f, 0xa1, 0x69, 0xa4, 0x05, 0x0f, 0x21, + 0x28, 0xa5, 0xae, 0x26, 0xb2, 0xdf, 0x2c, 0xcd, 0x33, 0x47, 0xe6, 0xc0, 0x0e, 0xcf, 0xd8, 0x76, + 0x96, 0x8d, 0xf8, 0x5b, 0x2d, 0xe5, 0xfa, 0xff, 0x68, 0x70, 0x35, 0x3a, 0xd4, 0x13, 0x3a, 0x74, + 0x79, 0x8e, 0x6e, 0xc1, 0x8a, 0x50, 0x98, 0x8c, 0xe6, 0xf0, 0x60, 0x6e, 0x89, 0xc3, 0xe4, 0x65, + 0x6c, 0xc1, 0x4a, 0x68, 0x06, 0x43, 0x1c, 0x66, 0xc7, 0x70, 0x7e, 0x2f, 0xf1, 0x46, 0x79, 0xcc, + 0x2c, 0x87, 0xaa, 0xcf, 0xf0, 0xcb, 0x38, 0x62, 0x6b, 0x85, 0x0a, 0x80, 0x37, 0x76, 0xc5, 0x2a, + 0xf5, 0x53, 0xb8, 0xce, 0x2f, 0x07, 0x1f, 0xca, 0x14, 0xcd, 0x55, 0x53, 0x57, 0xae, 0x3b, 0x63, + 0x31, 0xfe, 0x40, 0x83, 0x1b, 0x13, 0x30, 0xcf, 0x93, 0x4d, 0xbc, 0xa7, 0xc4, 0x3e, 0x21, 0xf7, + 0x93, 0xf0, 0xf2, 0x5b, 0x70, 0x32, 0x91, 0x9f, 0x95, 0x60, 0x31, 0xd7, 0xe9, 0xc2, 0x32, 0xf7, + 0x32, 0x20, 0xca, 0x84, 0xf8, 0x05, 0x1b, 0x4b, 0xa7, 0x85, 0x6b, 0xea, 0x78, 0x63, 0x37, 0x7e, + 0xbd, 0x46, 0x33, 0x6a, 0x64, 0xf3, 0xde, 0xbc, 0xa2, 0x1e, 0x73, 0xae, 0x34, 0xf9, 0xa1, 0x42, + 0x8e, 0xc0, 0x8d, 0xbd, 0xb1, 0xcb, 0x8b, 0xef, 0x82, 0xcb, 0xdc, 0xdd, 0x50, 0x54, 0x12, 0x18, + 0x1d, 0xc1, 0x22, 0xbb, 0xaa, 0x35, 0x0e, 0x87, 0x3e, 0x0d, 0xe8, 0x19, 0x5d, 0xdc, 0xa9, 0x7d, + 0x67, 0x66, 0x4c, 0x1f, 0x88, 0xd1, 0x94, 0x78, 0x11, 0xd3, 0x7b, 0x32, 0x34, 0xc2, 0x63, 0x7b, + 0x03, 0xdf, 0x8d, 0xf1, 0x54, 0x2e, 0x88, 0x67, 0x57, 0x8c, 0x96, 0xf1, 0xa4, 0xa1, 0xbd, 0x6d, + 0x58, 0x51, 0x2e, 0x7d, 0x9a, 0x1b, 0x2d, 0xa7, 0xf3, 0x83, 0xbb, 0xb0, 0xac, 0x5a, 0xd5, 0x25, + 0xe6, 0xc8, 0x51, 0x7c, 0x91, 0x39, 0xf4, 0x3f, 0x29, 0x40, 0x73, 0x07, 0x3b, 0x38, 0xc4, 0x4f, + 0xf7, 0xcc, 0x33, 0x77, 0x80, 0x5b, 0xcc, 0x1f, 0xe0, 0xe6, 0x4e, 0xa3, 0x4b, 0x8a, 0xd3, 0xe8, + 0x1b, 0xf1, 0x21, 0x3c, 0x9d, 0xa5, 0x2c, 0x7b, 0x68, 0x0b, 0xbd, 0x01, 0x8d, 0x51, 0x60, 0xbb, + 0x66, 0x70, 0xd6, 0x7f, 0x84, 0xcf, 0x88, 0x70, 0x1a, 0x5d, 0xa5, 0xdb, 0xd9, 0xdd, 0x21, 0x46, + 0x5d, 0xf4, 0x7e, 0x17, 0x9f, 0xb1, 0x03, 0xfe, 0x38, 0xd9, 0xe0, 0x57, 0xb1, 0x4a, 0x46, 0x0a, + 0xb2, 0xbe, 0x0a, 0xb5, 0xf8, 0xc6, 0x0b, 0xaa, 0x42, 0xe9, 0xde, 0xd8, 0x71, 0x3a, 0x57, 0x50, + 0x0d, 0xca, 0x2c, 0x1d, 0xe9, 0x68, 0xeb, 0xdf, 0x83, 0x5a, 0x7c, 0x6a, 0x8f, 0xea, 0xb0, 0xf0, + 0xd0, 0x7b, 0xd7, 0xf3, 0x4f, 0xbd, 0xce, 0x15, 0xb4, 0x00, 0xc5, 0x3b, 0x8e, 0xd3, 0xd1, 0x50, + 0x13, 0x6a, 0x07, 0x61, 0x80, 0x4d, 0xca, 0xb3, 0x4e, 0x01, 0xb5, 0x00, 0xde, 0xb1, 0x49, 0xe8, + 0x07, 0xf6, 0xc0, 0x74, 0x3a, 0xc5, 0xf5, 0x4f, 0xa1, 0x25, 0x17, 0x71, 0x51, 0x03, 0xaa, 0x7b, + 0x7e, 0xf8, 0xf6, 0x27, 0x36, 0x09, 0x3b, 0x57, 0x68, 0xff, 0x3d, 0x3f, 0xdc, 0x0f, 0x30, 0xc1, + 0x5e, 0xd8, 0xd1, 0x10, 0x40, 0xe5, 0x03, 0x6f, 0xc7, 0x26, 0x8f, 0x3a, 0x05, 0xb4, 0x24, 0xce, + 0x67, 0x4c, 0x67, 0x57, 0x54, 0x46, 0x3b, 0x45, 0x3a, 0x3c, 0xfe, 0x2a, 0xa1, 0x0e, 0x34, 0xe2, + 0x2e, 0xf7, 0xf7, 0x1f, 0x76, 0xca, 0x94, 0x7a, 0xfe, 0xb3, 0xb2, 0x6e, 0x41, 0x27, 0x7b, 0xae, + 0x48, 0xe7, 0xe4, 0x8b, 0x88, 0x41, 0x9d, 0x2b, 0x74, 0x65, 0xe2, 0x60, 0xb7, 0xa3, 0xa1, 0x36, + 0xd4, 0x53, 0xc7, 0xa4, 0x9d, 0x02, 0x05, 0xdc, 0x0f, 0x46, 0x03, 0x21, 0x50, 0x9c, 0x04, 0x2a, + 0x9d, 0x3b, 0x74, 0x27, 0x4a, 0xeb, 0x77, 0xa1, 0x1a, 0x85, 0xfc, 0xb4, 0xab, 0xd8, 0x22, 0xfa, + 0xd9, 0xb9, 0x82, 0x16, 0xa1, 0x29, 0x3d, 0x89, 0xea, 0x68, 0x08, 0x41, 0x4b, 0x7e, 0xb4, 0xd8, + 0x29, 0xac, 0x6f, 0x01, 0x24, 0xa1, 0x33, 0x25, 0x67, 0xd7, 0x3b, 0x31, 0x1d, 0xdb, 0xe2, 0xb4, + 0xd1, 0x26, 0xba, 0xbb, 0x6c, 0x77, 0xb8, 0xa2, 0x76, 0x0a, 0xeb, 0xeb, 0x50, 0x8d, 0xc2, 0x41, + 0x0a, 0x37, 0xb0, 0xeb, 0x9f, 0x60, 0xce, 0x99, 0x03, 0x4c, 0xb7, 0xb2, 0x06, 0xe5, 0x3b, 0x2e, + 0xf6, 0xac, 0x4e, 0x61, 0xeb, 0xdf, 0x96, 0x00, 0xf8, 0xa9, 0xa0, 0xef, 0x07, 0x16, 0x72, 0xd8, + 0xed, 0x80, 0x6d, 0xdf, 0x1d, 0xf9, 0x5e, 0x74, 0x64, 0x41, 0xd0, 0x46, 0x26, 0x55, 0xe7, 0x1f, + 0xf9, 0x8e, 0x62, 0x23, 0x7a, 0xcf, 0x29, 0xfb, 0x67, 0x3a, 0xeb, 0x57, 0x90, 0xcb, 0xb0, 0xd1, + 0xe4, 0xf6, 0x81, 0x3d, 0x78, 0x14, 0x1f, 0x25, 0x4e, 0x7e, 0x39, 0x98, 0xe9, 0x1a, 0xe1, 0xbb, + 0xa5, 0xc4, 0x77, 0x10, 0x06, 0xb6, 0x37, 0x8c, 0xfc, 0x9f, 0x7e, 0x05, 0x3d, 0xce, 0xbc, 0x5b, + 0x8c, 0x10, 0x6e, 0xcd, 0xf2, 0x54, 0xf1, 0x72, 0x28, 0x1d, 0x68, 0x67, 0x1e, 0x88, 0xa3, 0x75, + 0xf5, 0x3b, 0x12, 0xd5, 0x63, 0xf6, 0xde, 0x4b, 0x33, 0xf5, 0x8d, 0xb1, 0xd9, 0xd0, 0x92, 0x5f, + 0x36, 0xa3, 0xaf, 0x4d, 0x9a, 0x20, 0xf7, 0x92, 0xad, 0xb7, 0x3e, 0x4b, 0xd7, 0x18, 0xd5, 0x47, + 0x5c, 0x56, 0xa7, 0xa1, 0x52, 0xbe, 0xfa, 0xeb, 0x9d, 0x17, 0x7a, 0xe8, 0x57, 0xd0, 0x8f, 0x69, + 0x94, 0x90, 0x79, 0x6f, 0x87, 0x5e, 0x56, 0x7b, 0x36, 0xf5, 0xb3, 0xbc, 0x69, 0x18, 0x3e, 0xca, + 0x6a, 0xda, 0x64, 0xea, 0x73, 0x2f, 0x70, 0x67, 0xa7, 0x3e, 0x35, 0xfd, 0x79, 0xd4, 0x5f, 0x18, + 0x83, 0xc3, 0x13, 0x26, 0xc5, 0x4b, 0x9f, 0xac, 0x28, 0x27, 0xf9, 0xca, 0xe4, 0x67, 0x41, 0xd3, + 0xb0, 0x8d, 0x99, 0x92, 0x66, 0x8f, 0xc3, 0x5f, 0x99, 0x50, 0x68, 0x57, 0x3f, 0x31, 0xec, 0x6d, + 0xcc, 0xda, 0x3d, 0x2d, 0xcb, 0xf2, 0x2b, 0x36, 0x35, 0x8b, 0x94, 0x2f, 0xef, 0xd4, 0xb2, 0xac, + 0x7e, 0x14, 0xa7, 0x5f, 0x41, 0x0f, 0x24, 0xbb, 0x8e, 0x5e, 0x98, 0x24, 0x0a, 0xf2, 0xfd, 0x98, + 0x69, 0xfb, 0xf6, 0x2b, 0x80, 0xb8, 0xa6, 0x7a, 0x47, 0xf6, 0x70, 0x1c, 0x98, 0x5c, 0x8c, 0x27, + 0x19, 0xb7, 0x7c, 0xd7, 0x08, 0xcd, 0xd7, 0x2f, 0x30, 0x22, 0x5e, 0x52, 0x1f, 0xe0, 0x3e, 0x0e, + 0xdf, 0xc7, 0x61, 0x60, 0x0f, 0x48, 0x76, 0x45, 0x89, 0xfd, 0x16, 0x1d, 0x22, 0x54, 0x2f, 0x4e, + 0xed, 0x17, 0x23, 0x38, 0x84, 0xfa, 0x7d, 0x9a, 0x41, 0xb1, 0xa8, 0x90, 0xa0, 0x89, 0x23, 0xa3, + 0x1e, 0x11, 0x8a, 0xb5, 0xe9, 0x1d, 0xd3, 0xc6, 0x33, 0xf3, 0xa2, 0x0f, 0x4d, 0x64, 0x6c, 0xfe, + 0x9d, 0xa1, 0xda, 0x78, 0x4e, 0x78, 0x22, 0xc8, 0x57, 0xc4, 0x0e, 0x7b, 0xde, 0xc1, 0xa6, 0x13, + 0x1e, 0x4f, 0x58, 0x51, 0xaa, 0xc7, 0xf9, 0x2b, 0x92, 0x3a, 0xc6, 0x38, 0x30, 0x2c, 0x71, 0x2d, + 0x94, 0x53, 0xcf, 0x4d, 0xf5, 0x14, 0xf9, 0x9e, 0x33, 0x8a, 0x9e, 0x09, 0x8b, 0x3b, 0x81, 0x3f, + 0x92, 0x91, 0xbc, 0xa2, 0x44, 0x92, 0xeb, 0x37, 0x23, 0x8a, 0x1f, 0x40, 0x23, 0xca, 0xf0, 0x59, + 0x4e, 0xa2, 0xde, 0x85, 0x74, 0x97, 0x19, 0x27, 0xfe, 0x18, 0xda, 0x99, 0xd2, 0x81, 0x9a, 0xe9, + 0xea, 0xfa, 0xc2, 0xb4, 0xd9, 0x4f, 0x01, 0xb1, 0x67, 0x9a, 0xd2, 0x13, 0xf1, 0x09, 0xf1, 0x4d, + 0xbe, 0x63, 0x84, 0x64, 0x73, 0xe6, 0xfe, 0x31, 0xe7, 0x7f, 0x15, 0x56, 0x94, 0xe9, 0x79, 0xd6, + 0x20, 0x88, 0x0b, 0xb1, 0xe7, 0xd4, 0x10, 0xb2, 0x06, 0xe1, 0xdc, 0x11, 0x11, 0xfe, 0xad, 0x7f, + 0x6e, 0x43, 0x8d, 0xc5, 0x79, 0x8c, 0x5b, 0xff, 0x1f, 0xe6, 0x3d, 0xd9, 0x30, 0xef, 0x63, 0x68, + 0x67, 0xde, 0x17, 0xaa, 0x85, 0x56, 0xfd, 0x08, 0x71, 0x86, 0x68, 0x45, 0x7e, 0x9a, 0xa7, 0x76, + 0x85, 0xca, 0xe7, 0x7b, 0xd3, 0xe6, 0xfe, 0x90, 0x3f, 0xcd, 0x8d, 0x6f, 0x29, 0xbc, 0x38, 0xb1, + 0x78, 0x2f, 0x5f, 0x6c, 0xfd, 0xfc, 0xa3, 0xa0, 0x2f, 0x77, 0x04, 0xfa, 0x31, 0xb4, 0x33, 0x4f, + 0x47, 0xd4, 0x12, 0xa3, 0x7e, 0x5f, 0x32, 0x6d, 0xf6, 0x5f, 0x60, 0xf0, 0x64, 0xc1, 0x92, 0xe2, + 0xa6, 0x3e, 0xda, 0x98, 0x14, 0x88, 0xaa, 0xaf, 0xf4, 0x4f, 0x5f, 0x50, 0x53, 0x52, 0xd3, 0xac, + 0xbf, 0x49, 0x88, 0xcc, 0xfe, 0xb7, 0x4c, 0xef, 0xe5, 0xd9, 0xfe, 0x88, 0x26, 0x5e, 0xd0, 0x01, + 0x54, 0xf8, 0x83, 0x12, 0xf4, 0xac, 0xfa, 0x10, 0x23, 0xf5, 0xd8, 0xa4, 0x37, 0xed, 0x49, 0x0a, + 0x19, 0x3b, 0x21, 0x61, 0x93, 0x96, 0x99, 0xf5, 0x45, 0xca, 0xaa, 0x7e, 0xfa, 0x65, 0x47, 0x6f, + 0xfa, 0x63, 0x8e, 0x68, 0xd2, 0xff, 0xdb, 0x11, 0xe6, 0x27, 0xec, 0xe9, 0x40, 0xf6, 0x72, 0x0c, + 0xda, 0xb8, 0xd8, 0x0d, 0x9f, 0xde, 0xe6, 0xcc, 0xfd, 0x63, 0xcc, 0x3f, 0x82, 0x4e, 0xf6, 0x40, + 0x0a, 0xbd, 0x34, 0x49, 0x9e, 0x55, 0x38, 0xa7, 0x08, 0xf3, 0xf7, 0xa1, 0xc2, 0x2b, 0x91, 0x6a, + 0x09, 0x93, 0xaa, 0x94, 0x53, 0xe6, 0xba, 0xfb, 0x8d, 0x8f, 0xb6, 0x86, 0x76, 0x78, 0x3c, 0x3e, + 0xa4, 0x2d, 0x9b, 0xbc, 0xeb, 0x2b, 0xb6, 0x2f, 0x7e, 0x6d, 0x46, 0xbc, 0xdc, 0x64, 0xa3, 0x37, + 0x19, 0x82, 0xd1, 0xe1, 0x61, 0x85, 0x7d, 0xde, 0xfe, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, + 0x7b, 0x3b, 0x91, 0xd9, 0x4f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/internal/proto/segcore.proto b/internal/proto/segcore.proto index 7acb66cdc2..92b056bda3 100644 --- a/internal/proto/segcore.proto +++ b/internal/proto/segcore.proto @@ -3,6 +3,7 @@ package milvus.proto.segcore; option go_package = "github.com/milvus-io/milvus/internal/proto/segcorepb"; import "schema.proto"; +import "common.proto"; message RetrieveResults { schema.IDs ids = 1; @@ -25,4 +26,19 @@ message LoadSegmentMeta { message InsertRecord { repeated schema.FieldData fields_data = 1; int64 num_rows = 2; +} + +message FieldIndexMeta { + int64 fieldID = 1; + int64 collectionID = 2; + string index_name = 3; + repeated common.KeyValuePair type_params = 4; + repeated common.KeyValuePair index_params = 5; + bool is_auto_index = 6; + repeated common.KeyValuePair user_index_params = 7; +} + +message CollectionIndexMeta { + int64 maxIndexRowCount = 1; + repeated FieldIndexMeta index_metas = 2; } \ No newline at end of file diff --git a/internal/proto/segcorepb/segcore.pb.go b/internal/proto/segcorepb/segcore.pb.go index c6b8426073..4af28bc6c5 100644 --- a/internal/proto/segcorepb/segcore.pb.go +++ b/internal/proto/segcorepb/segcore.pb.go @@ -6,6 +6,7 @@ package segcorepb import ( fmt "fmt" proto "github.com/golang/protobuf/proto" + commonpb "github.com/milvus-io/milvus-proto/go-api/commonpb" schemapb "github.com/milvus-io/milvus-proto/go-api/schemapb" math "math" ) @@ -226,38 +227,187 @@ func (m *InsertRecord) GetNumRows() int64 { return 0 } +type FieldIndexMeta struct { + FieldID int64 `protobuf:"varint,1,opt,name=fieldID,proto3" json:"fieldID,omitempty"` + CollectionID int64 `protobuf:"varint,2,opt,name=collectionID,proto3" json:"collectionID,omitempty"` + IndexName string `protobuf:"bytes,3,opt,name=index_name,json=indexName,proto3" json:"index_name,omitempty"` + TypeParams []*commonpb.KeyValuePair `protobuf:"bytes,4,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` + IndexParams []*commonpb.KeyValuePair `protobuf:"bytes,5,rep,name=index_params,json=indexParams,proto3" json:"index_params,omitempty"` + IsAutoIndex bool `protobuf:"varint,6,opt,name=is_auto_index,json=isAutoIndex,proto3" json:"is_auto_index,omitempty"` + UserIndexParams []*commonpb.KeyValuePair `protobuf:"bytes,7,rep,name=user_index_params,json=userIndexParams,proto3" json:"user_index_params,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldIndexMeta) Reset() { *m = FieldIndexMeta{} } +func (m *FieldIndexMeta) String() string { return proto.CompactTextString(m) } +func (*FieldIndexMeta) ProtoMessage() {} +func (*FieldIndexMeta) Descriptor() ([]byte, []int) { + return fileDescriptor_1d79fce784797357, []int{4} +} + +func (m *FieldIndexMeta) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldIndexMeta.Unmarshal(m, b) +} +func (m *FieldIndexMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldIndexMeta.Marshal(b, m, deterministic) +} +func (m *FieldIndexMeta) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldIndexMeta.Merge(m, src) +} +func (m *FieldIndexMeta) XXX_Size() int { + return xxx_messageInfo_FieldIndexMeta.Size(m) +} +func (m *FieldIndexMeta) XXX_DiscardUnknown() { + xxx_messageInfo_FieldIndexMeta.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldIndexMeta proto.InternalMessageInfo + +func (m *FieldIndexMeta) GetFieldID() int64 { + if m != nil { + return m.FieldID + } + return 0 +} + +func (m *FieldIndexMeta) GetCollectionID() int64 { + if m != nil { + return m.CollectionID + } + return 0 +} + +func (m *FieldIndexMeta) GetIndexName() string { + if m != nil { + return m.IndexName + } + return "" +} + +func (m *FieldIndexMeta) GetTypeParams() []*commonpb.KeyValuePair { + if m != nil { + return m.TypeParams + } + return nil +} + +func (m *FieldIndexMeta) GetIndexParams() []*commonpb.KeyValuePair { + if m != nil { + return m.IndexParams + } + return nil +} + +func (m *FieldIndexMeta) GetIsAutoIndex() bool { + if m != nil { + return m.IsAutoIndex + } + return false +} + +func (m *FieldIndexMeta) GetUserIndexParams() []*commonpb.KeyValuePair { + if m != nil { + return m.UserIndexParams + } + return nil +} + +type CollectionIndexMeta struct { + MaxIndexRowCount int64 `protobuf:"varint,1,opt,name=maxIndexRowCount,proto3" json:"maxIndexRowCount,omitempty"` + IndexMetas []*FieldIndexMeta `protobuf:"bytes,2,rep,name=index_metas,json=indexMetas,proto3" json:"index_metas,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CollectionIndexMeta) Reset() { *m = CollectionIndexMeta{} } +func (m *CollectionIndexMeta) String() string { return proto.CompactTextString(m) } +func (*CollectionIndexMeta) ProtoMessage() {} +func (*CollectionIndexMeta) Descriptor() ([]byte, []int) { + return fileDescriptor_1d79fce784797357, []int{5} +} + +func (m *CollectionIndexMeta) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CollectionIndexMeta.Unmarshal(m, b) +} +func (m *CollectionIndexMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CollectionIndexMeta.Marshal(b, m, deterministic) +} +func (m *CollectionIndexMeta) XXX_Merge(src proto.Message) { + xxx_messageInfo_CollectionIndexMeta.Merge(m, src) +} +func (m *CollectionIndexMeta) XXX_Size() int { + return xxx_messageInfo_CollectionIndexMeta.Size(m) +} +func (m *CollectionIndexMeta) XXX_DiscardUnknown() { + xxx_messageInfo_CollectionIndexMeta.DiscardUnknown(m) +} + +var xxx_messageInfo_CollectionIndexMeta proto.InternalMessageInfo + +func (m *CollectionIndexMeta) GetMaxIndexRowCount() int64 { + if m != nil { + return m.MaxIndexRowCount + } + return 0 +} + +func (m *CollectionIndexMeta) GetIndexMetas() []*FieldIndexMeta { + if m != nil { + return m.IndexMetas + } + return nil +} + func init() { proto.RegisterType((*RetrieveResults)(nil), "milvus.proto.segcore.RetrieveResults") proto.RegisterType((*LoadFieldMeta)(nil), "milvus.proto.segcore.LoadFieldMeta") proto.RegisterType((*LoadSegmentMeta)(nil), "milvus.proto.segcore.LoadSegmentMeta") proto.RegisterType((*InsertRecord)(nil), "milvus.proto.segcore.InsertRecord") + proto.RegisterType((*FieldIndexMeta)(nil), "milvus.proto.segcore.FieldIndexMeta") + proto.RegisterType((*CollectionIndexMeta)(nil), "milvus.proto.segcore.CollectionIndexMeta") } func init() { proto.RegisterFile("segcore.proto", fileDescriptor_1d79fce784797357) } var fileDescriptor_1d79fce784797357 = []byte{ - // 363 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x90, 0xc1, 0x4b, 0xeb, 0x40, - 0x10, 0xc6, 0x49, 0xc3, 0xeb, 0x6b, 0xb7, 0x2d, 0x85, 0xf0, 0x78, 0x44, 0x45, 0x29, 0xe9, 0xa5, - 0x08, 0x26, 0x50, 0x45, 0xf0, 0x24, 0x68, 0x11, 0x0a, 0x7a, 0xd9, 0x7a, 0xf2, 0x12, 0xb6, 0xc9, - 0xb4, 0x5d, 0xcd, 0xee, 0x96, 0xdd, 0x49, 0x53, 0xfa, 0x87, 0xf8, 0xf7, 0x4a, 0x36, 0x11, 0xad, - 0xf4, 0xe2, 0x6d, 0xe7, 0xdb, 0xdf, 0xcc, 0x37, 0xf3, 0x91, 0x9e, 0x81, 0x65, 0xa2, 0x34, 0x84, - 0x6b, 0xad, 0x50, 0x79, 0xff, 0x04, 0xcf, 0x36, 0xb9, 0xa9, 0xaa, 0xb0, 0xfe, 0x3b, 0xee, 0x9a, - 0x64, 0x05, 0x82, 0x55, 0x6a, 0xf0, 0xee, 0x90, 0x3e, 0x05, 0xd4, 0x1c, 0x36, 0x40, 0xc1, 0xe4, - 0x19, 0x1a, 0xef, 0x9c, 0xb8, 0x3c, 0x35, 0xbe, 0x33, 0x70, 0x46, 0x9d, 0xb1, 0x1f, 0xee, 0x4f, - 0xa9, 0x9a, 0xa7, 0x13, 0x43, 0x4b, 0xc8, 0xfb, 0x4f, 0x9a, 0x6a, 0xb1, 0x30, 0x80, 0x7e, 0x63, - 0xe0, 0x8e, 0x5c, 0x5a, 0x57, 0xde, 0x2d, 0xe9, 0x2c, 0x38, 0x64, 0xa9, 0x89, 0x53, 0x86, 0xcc, - 0x77, 0x07, 0xee, 0xa8, 0x33, 0x3e, 0x3b, 0x38, 0xeb, 0xa1, 0xe4, 0x26, 0x0c, 0x19, 0x25, 0x55, - 0x4b, 0xf9, 0x0e, 0x36, 0xa4, 0xf7, 0xa8, 0x58, 0x6a, 0x3f, 0x9f, 0x00, 0x99, 0x37, 0x24, 0x3d, - 0xc1, 0x65, 0x8c, 0x5c, 0x80, 0x41, 0x26, 0xd6, 0x76, 0x3f, 0x97, 0x76, 0x05, 0x97, 0xcf, 0x9f, - 0x9a, 0x85, 0xd8, 0xf6, 0x1b, 0xd4, 0xa8, 0x21, 0xb6, 0xfd, 0x82, 0x4e, 0x48, 0x5b, 0xab, 0x22, - 0x4e, 0x54, 0x2e, 0xd1, 0x77, 0x2d, 0xd0, 0xd2, 0xaa, 0xb8, 0x2f, 0xeb, 0xe0, 0x8d, 0xf4, 0x4b, - 0xdf, 0x19, 0x2c, 0x05, 0x48, 0xb4, 0xce, 0x37, 0xe4, 0x8f, 0x00, 0x64, 0x65, 0x22, 0xe5, 0x15, - 0xc3, 0xf0, 0x50, 0xae, 0xe1, 0xde, 0xb6, 0xb4, 0xea, 0xf0, 0x4e, 0x09, 0x41, 0x85, 0x2c, 0x8b, - 0x0d, 0xdf, 0x41, 0xbd, 0x4c, 0xdb, 0x2a, 0x33, 0xbe, 0x83, 0xe0, 0x95, 0x74, 0xa7, 0xd2, 0x80, - 0x46, 0x0a, 0x89, 0xd2, 0xe9, 0xcf, 0xd4, 0x9c, 0xdf, 0xa6, 0xe6, 0x1d, 0x91, 0x96, 0xcc, 0x45, - 0xac, 0x55, 0x61, 0x6a, 0xb7, 0xbf, 0x32, 0x17, 0x54, 0x15, 0xe6, 0xee, 0xfa, 0xe5, 0x6a, 0xc9, - 0x71, 0x95, 0xcf, 0xc3, 0x44, 0x89, 0xa8, 0x1a, 0x79, 0xc1, 0x55, 0xfd, 0x8a, 0xb8, 0x44, 0xd0, - 0x92, 0x65, 0x91, 0x75, 0x89, 0xea, 0xab, 0xd6, 0xf3, 0x79, 0xd3, 0x0a, 0x97, 0x1f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0xd6, 0x48, 0x04, 0x17, 0x5d, 0x02, 0x00, 0x00, + // 564 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x5d, 0x6f, 0xd3, 0x30, + 0x14, 0x55, 0x1b, 0xf6, 0xd1, 0x9b, 0x94, 0x81, 0x41, 0x28, 0x0c, 0x81, 0x4a, 0xc6, 0x43, 0x35, + 0x89, 0x56, 0x1a, 0x08, 0x89, 0x27, 0xc4, 0x56, 0x90, 0x22, 0x18, 0x9a, 0x3c, 0xc4, 0x03, 0x2f, + 0x91, 0x97, 0xdc, 0x6d, 0x86, 0xd8, 0xae, 0x6c, 0x67, 0xed, 0xf6, 0x0b, 0xf8, 0x05, 0xfc, 0x48, + 0x7e, 0x05, 0xb2, 0xe3, 0xb1, 0x15, 0xfa, 0x30, 0xde, 0x7c, 0x4f, 0xee, 0x39, 0xe7, 0xde, 0x93, + 0x0b, 0x7d, 0x83, 0x27, 0xa5, 0xd2, 0x38, 0x9a, 0x6a, 0x65, 0x15, 0xb9, 0x2f, 0x78, 0x7d, 0xd6, + 0x98, 0xb6, 0x1a, 0x85, 0x6f, 0x9b, 0x89, 0x29, 0x4f, 0x51, 0xb0, 0x16, 0xdd, 0x4c, 0x4a, 0x25, + 0x84, 0x92, 0x6d, 0x95, 0xfd, 0xec, 0xc0, 0x06, 0x45, 0xab, 0x39, 0x9e, 0x21, 0x45, 0xd3, 0xd4, + 0xd6, 0x90, 0x6d, 0x88, 0x78, 0x65, 0xd2, 0xce, 0xa0, 0x33, 0x8c, 0x77, 0xd2, 0xd1, 0xa2, 0x66, + 0x2b, 0x95, 0x4f, 0x0c, 0x75, 0x4d, 0xe4, 0x01, 0xac, 0xaa, 0xe3, 0x63, 0x83, 0x36, 0xed, 0x0e, + 0xa2, 0x61, 0x44, 0x43, 0x45, 0xde, 0x40, 0x7c, 0xcc, 0xb1, 0xae, 0x4c, 0x51, 0x31, 0xcb, 0xd2, + 0x68, 0x10, 0x0d, 0xe3, 0x9d, 0x27, 0x4b, 0xb5, 0xde, 0xbb, 0xbe, 0x09, 0xb3, 0x8c, 0x42, 0x4b, + 0x71, 0xef, 0xec, 0x0c, 0xfa, 0x1f, 0x15, 0xab, 0xfc, 0xc7, 0x7d, 0xb4, 0x8c, 0x6c, 0x41, 0x5f, + 0x70, 0x59, 0x58, 0x2e, 0xd0, 0x58, 0x26, 0xa6, 0x7e, 0xbe, 0x88, 0x26, 0x82, 0xcb, 0xcf, 0x97, + 0x98, 0x6f, 0x62, 0xf3, 0x6b, 0x4d, 0xdd, 0xd0, 0xc4, 0xe6, 0x57, 0x4d, 0x8f, 0xa0, 0xa7, 0xd5, + 0xac, 0x28, 0x55, 0x23, 0x6d, 0x1a, 0xf9, 0x86, 0x75, 0xad, 0x66, 0x7b, 0xae, 0xce, 0xbe, 0xc3, + 0x86, 0xf3, 0x3d, 0xc4, 0x13, 0x81, 0xd2, 0x7a, 0xe7, 0xd7, 0xb0, 0x22, 0xd0, 0x32, 0x97, 0x88, + 0xdb, 0x62, 0x6b, 0xb4, 0x2c, 0xe5, 0xd1, 0xc2, 0xb4, 0xb4, 0x65, 0x90, 0xc7, 0x00, 0x56, 0x59, + 0x56, 0x17, 0x86, 0x5f, 0x60, 0x18, 0xa6, 0xe7, 0x91, 0x43, 0x7e, 0x81, 0xd9, 0x37, 0x48, 0x72, + 0x69, 0x50, 0x5b, 0x8a, 0xa5, 0xd2, 0xd5, 0xdf, 0xa9, 0x75, 0xfe, 0x37, 0x35, 0xf2, 0x10, 0xd6, + 0x65, 0x23, 0x0a, 0xad, 0x66, 0x26, 0xb8, 0xad, 0xc9, 0x46, 0x50, 0x35, 0x33, 0xd9, 0xaf, 0x2e, + 0xdc, 0xf6, 0xa4, 0x5c, 0x56, 0x38, 0xf7, 0x8b, 0xa5, 0xb0, 0xe6, 0xb9, 0xf9, 0x24, 0x84, 0x79, + 0x59, 0x92, 0x0c, 0x92, 0x52, 0xd5, 0x35, 0x96, 0x96, 0x2b, 0x99, 0x4f, 0x2e, 0x63, 0xbc, 0x8e, + 0xb9, 0xdd, 0xb8, 0x93, 0x2a, 0x24, 0x13, 0xe8, 0x73, 0xec, 0xd1, 0x9e, 0x47, 0x3e, 0x31, 0x81, + 0x64, 0x17, 0x62, 0x7b, 0x3e, 0xc5, 0x62, 0xca, 0x34, 0x13, 0x26, 0xbd, 0xe5, 0x77, 0x79, 0xba, + 0xb8, 0x4b, 0x38, 0xc5, 0x0f, 0x78, 0xfe, 0x85, 0xd5, 0x0d, 0x1e, 0x30, 0xae, 0x29, 0x38, 0xd6, + 0x81, 0x27, 0x91, 0x09, 0x24, 0xad, 0x45, 0x10, 0x59, 0xb9, 0xa9, 0x48, 0xec, 0x69, 0x41, 0x25, + 0x83, 0x3e, 0x37, 0x05, 0x6b, 0xac, 0x2a, 0x3c, 0x9c, 0xae, 0x0e, 0x3a, 0xc3, 0x75, 0x1a, 0x73, + 0xf3, 0xb6, 0xb1, 0xca, 0xc7, 0x41, 0xf6, 0xe1, 0x6e, 0x63, 0x50, 0x17, 0x0b, 0x76, 0x6b, 0x37, + 0xb5, 0xdb, 0x70, 0xdc, 0xfc, 0xca, 0x32, 0xfb, 0xd1, 0x81, 0x7b, 0x7b, 0x57, 0x61, 0xfd, 0x49, + 0x7c, 0x1b, 0xee, 0x08, 0x36, 0xf7, 0x35, 0x0d, 0x17, 0x17, 0xa2, 0xff, 0x07, 0x27, 0xef, 0xa0, + 0xdd, 0xa2, 0x68, 0x8f, 0xaf, 0xeb, 0x87, 0x79, 0xb6, 0xfc, 0xf8, 0x16, 0x7f, 0x2c, 0x6d, 0x7f, + 0x8c, 0x7b, 0x9a, 0xdd, 0x57, 0x5f, 0x5f, 0x9e, 0x70, 0x7b, 0xda, 0x1c, 0xb9, 0xc9, 0xc7, 0x2d, + 0xfb, 0x39, 0x57, 0xe1, 0x35, 0xe6, 0xd2, 0xa2, 0x96, 0xac, 0x1e, 0x7b, 0xc1, 0x71, 0x10, 0x9c, + 0x1e, 0x1d, 0xad, 0x7a, 0xe0, 0xc5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x46, 0x25, 0x42, + 0x63, 0x04, 0x00, 0x00, } diff --git a/internal/querycoordv2/meta/coordinator_broker.go b/internal/querycoordv2/meta/coordinator_broker.go index 299c76c7ec..050ed7a6ee 100644 --- a/internal/querycoordv2/meta/coordinator_broker.go +++ b/internal/querycoordv2/meta/coordinator_broker.go @@ -45,6 +45,7 @@ type Broker interface { GetCollectionSchema(ctx context.Context, collectionID UniqueID) (*schemapb.CollectionSchema, error) GetPartitions(ctx context.Context, collectionID UniqueID) ([]UniqueID, error) GetRecoveryInfo(ctx context.Context, collectionID UniqueID, partitionID UniqueID) ([]*datapb.VchannelInfo, []*datapb.SegmentBinlogs, error) + DescribeIndex(ctx context.Context, collectionID UniqueID) ([]*indexpb.IndexInfo, error) GetSegmentInfo(ctx context.Context, segmentID ...UniqueID) (*datapb.GetSegmentInfoResponse, error) GetIndexInfo(ctx context.Context, collectionID UniqueID, segmentID UniqueID) ([]*querypb.FieldIndexInfo, error) GetRecoveryInfoV2(ctx context.Context, collectionID UniqueID, partitionIDs ...UniqueID) ([]*datapb.VchannelInfo, []*datapb.SegmentInfo, error) @@ -226,3 +227,20 @@ func (broker *CoordinatorBroker) GetIndexInfo(ctx context.Context, collectionID return indexes, nil } + +func (broker *CoordinatorBroker) DescribeIndex(ctx context.Context, collectionID UniqueID) ([]*indexpb.IndexInfo, error) { + ctx, cancel := context.WithTimeout(ctx, brokerRPCTimeout) + defer cancel() + + resp, err := broker.dataCoord.DescribeIndex(ctx, &indexpb.DescribeIndexRequest{ + CollectionID: collectionID, + }) + + if err != nil || resp.GetStatus().GetErrorCode() != commonpb.ErrorCode_Success { + log.Error("failed to fetch index meta", + zap.Int64("collection", collectionID), + zap.Error(err)) + return nil, err + } + return resp.IndexInfos, nil +} diff --git a/internal/querycoordv2/meta/mock_broker.go b/internal/querycoordv2/meta/mock_broker.go index cfb028b7c8..7a078ef465 100644 --- a/internal/querycoordv2/meta/mock_broker.go +++ b/internal/querycoordv2/meta/mock_broker.go @@ -4,6 +4,7 @@ package meta import ( context "context" + "github.com/milvus-io/milvus/internal/proto/indexpb" datapb "github.com/milvus-io/milvus/internal/proto/datapb" @@ -122,6 +123,53 @@ func (_c *MockBroker_GetIndexInfo_Call) Return(_a0 []*querypb.FieldIndexInfo, _a return _c } +// DescribeIndex provides a mock function with given fields: ctx, collectionID, segmentID +func (_m *MockBroker) DescribeIndex(ctx context.Context, collectionID int64) ([]*indexpb.IndexInfo, error) { + ret := _m.Called(ctx, collectionID) + + var r0 []*indexpb.IndexInfo + if rf, ok := ret.Get(0).(func(context.Context, int64) []*indexpb.IndexInfo); ok { + r0 = rf(ctx, collectionID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*indexpb.IndexInfo) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, collectionID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockBroker_DescribeIndex_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DescribeIndex' +type MockBroker_DescribeIndex_Call struct { + *mock.Call +} + +// DescribeIndex is a helper method to define mock.On call +// - ctx context.Context +// - collectionID int64 +func (_e *MockBroker_Expecter) DescribeIndex(ctx interface{}, collectionID interface{}) *MockBroker_DescribeIndex_Call { + return &MockBroker_DescribeIndex_Call{Call: _e.mock.On("DescribeIndex", ctx, collectionID)} +} + +func (_c *MockBroker_DescribeIndex_Call) Run(run func(ctx context.Context, collectionID int64)) *MockBroker_DescribeIndex_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(int64)) + }) + return _c +} + +func (_c *MockBroker_DescribeIndex_Call) Return(_a0 []*indexpb.IndexInfo, _a1 error) *MockBroker_DescribeIndex_Call { + _c.Call.Return(_a0, _a1) + return _c +} + // GetPartitions provides a mock function with given fields: ctx, collectionID func (_m *MockBroker) GetPartitions(ctx context.Context, collectionID int64) ([]int64, error) { ret := _m.Called(ctx, collectionID) diff --git a/internal/querycoordv2/server_test.go b/internal/querycoordv2/server_test.go index 2a01997566..f47a16a481 100644 --- a/internal/querycoordv2/server_test.go +++ b/internal/querycoordv2/server_test.go @@ -521,6 +521,7 @@ func (suite *ServerSuite) hackServer() { ) suite.broker.EXPECT().GetCollectionSchema(mock.Anything, mock.Anything).Return(&schemapb.CollectionSchema{}, nil).Maybe() + suite.broker.EXPECT().DescribeIndex(mock.Anything, mock.Anything).Return(nil, nil).Maybe() for _, collection := range suite.collections { suite.broker.EXPECT().GetPartitions(mock.Anything, collection).Return(suite.partitions[collection], nil).Maybe() suite.expectGetRecoverInfo(collection) diff --git a/internal/querycoordv2/task/task_test.go b/internal/querycoordv2/task/task_test.go index fdf4d893d8..6d86dc9735 100644 --- a/internal/querycoordv2/task/task_test.go +++ b/internal/querycoordv2/task/task_test.go @@ -31,6 +31,7 @@ import ( "github.com/milvus-io/milvus/internal/kv" etcdkv "github.com/milvus-io/milvus/internal/kv/etcd" "github.com/milvus-io/milvus/internal/proto/datapb" + "github.com/milvus-io/milvus/internal/proto/indexpb" "github.com/milvus-io/milvus/internal/proto/querypb" "github.com/milvus-io/milvus/internal/querycoordv2/meta" . "github.com/milvus-io/milvus/internal/querycoordv2/params" @@ -185,6 +186,13 @@ func (suite *TaskSuite) TestSubscribeChannelTask() { Return(&schemapb.CollectionSchema{ Name: "TestSubscribeChannelTask", }, nil) + suite.broker.EXPECT().DescribeIndex(mock.Anything, suite.collection).Return([]*indexpb.IndexInfo{ + { + CollectionID: suite.collection, + TypeParams: []*commonpb.KeyValuePair{}, + IndexParams: []*commonpb.KeyValuePair{}, + }, + }, nil) for channel, segment := range suite.growingSegments { suite.broker.EXPECT().GetSegmentInfo(mock.Anything, segment). Return(&datapb.GetSegmentInfoResponse{Infos: []*datapb.SegmentInfo{ diff --git a/internal/querycoordv2/task/utils.go b/internal/querycoordv2/task/utils.go index 855c151900..00e201ab46 100644 --- a/internal/querycoordv2/task/utils.go +++ b/internal/querycoordv2/task/utils.go @@ -185,6 +185,13 @@ func fillSubChannelRequest( req *querypb.WatchDmChannelsRequest, broker meta.Broker, ) error { + indexes, err := broker.DescribeIndex(ctx, req.GetCollectionID()) + if err != nil { + log.Warn("fail to get index meta when fillSubChannelRequest", + zap.Int64("collectionId", req.GetCollectionID())) + } else { + req.IndexInfoList = indexes + } segmentIDs := typeutil.NewUniqueSet() for _, vchannel := range req.GetInfos() { segmentIDs.Insert(vchannel.GetFlushedSegmentIds()...) diff --git a/internal/querynodev2/delegator/delegator_data_test.go b/internal/querynodev2/delegator/delegator_data_test.go index 3025bf3f50..04c7c8ced4 100644 --- a/internal/querynodev2/delegator/delegator_data_test.go +++ b/internal/querynodev2/delegator/delegator_data_test.go @@ -96,6 +96,31 @@ func (s *DelegatorDataSuite) SetupTest() { }, }, }, + }, &segcorepb.CollectionIndexMeta{ + MaxIndexRowCount: 100, + IndexMetas: []*segcorepb.FieldIndexMeta{ + { + FieldID: 101, + CollectionID: s.collectionID, + IndexName: "binary_index", + TypeParams: []*commonpb.KeyValuePair{ + { + Key: "dim", + Value: "128", + }, + }, + IndexParams: []*commonpb.KeyValuePair{ + { + Key: "index_type", + Value: "BIN_IVF_FLAT", + }, + { + Key: "metric_type", + Value: "TANIMOTO", + }, + }, + }, + }, }, &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, }) diff --git a/internal/querynodev2/delegator/delegator_test.go b/internal/querynodev2/delegator/delegator_test.go index b3c4111f26..3b0ce110f8 100644 --- a/internal/querynodev2/delegator/delegator_test.go +++ b/internal/querynodev2/delegator/delegator_test.go @@ -34,6 +34,7 @@ import ( "github.com/milvus-io/milvus-proto/go-api/schemapb" "github.com/milvus-io/milvus/internal/proto/internalpb" "github.com/milvus-io/milvus/internal/proto/querypb" + "github.com/milvus-io/milvus/internal/proto/segcorepb" "github.com/milvus-io/milvus/internal/querynodev2/cluster" "github.com/milvus-io/milvus/internal/querynodev2/segments" "github.com/milvus-io/milvus/internal/querynodev2/tsafe" @@ -115,6 +116,31 @@ func (s *DelegatorSuite) SetupTest() { }, }, }, + }, &segcorepb.CollectionIndexMeta{ + MaxIndexRowCount: 100, + IndexMetas: []*segcorepb.FieldIndexMeta{ + { + FieldID: 101, + CollectionID: s.collectionID, + IndexName: "binary_index", + TypeParams: []*commonpb.KeyValuePair{ + { + Key: "dim", + Value: "128", + }, + }, + IndexParams: []*commonpb.KeyValuePair{ + { + Key: "index_type", + Value: "BIN_IVF_FLAT", + }, + { + Key: "metric_type", + Value: "TANIMOTO", + }, + }, + }, + }, }, &querypb.LoadMetaInfo{}) s.mq = &msgstream.MockMsgStream{} diff --git a/internal/querynodev2/local_worker_test.go b/internal/querynodev2/local_worker_test.go index e7925b1445..168efabd7b 100644 --- a/internal/querynodev2/local_worker_test.go +++ b/internal/querynodev2/local_worker_test.go @@ -18,6 +18,7 @@ package querynodev2 import ( "context" + "testing" "github.com/samber/lo" @@ -26,6 +27,7 @@ import ( "github.com/milvus-io/milvus-proto/go-api/schemapb" "github.com/milvus-io/milvus/internal/proto/querypb" + "github.com/milvus-io/milvus/internal/proto/segcorepb" "github.com/milvus-io/milvus/internal/querynodev2/segments" "github.com/milvus-io/milvus/internal/util/dependency" "github.com/milvus-io/milvus/pkg/util/etcd" @@ -42,6 +44,7 @@ type LocalWorkerTestSuite struct { partitionIDs []int64 segmentIDs []int64 schema *schemapb.CollectionSchema + indexMeta *segcorepb.CollectionIndexMeta // dependency node *QueryNode @@ -89,12 +92,13 @@ func (suite *LocalWorkerTestSuite) BeforeTest(suiteName, testName string) { suite.NoError(err) suite.schema = segments.GenTestCollectionSchema(suite.collectionName, schemapb.DataType_Int64) - collection := segments.NewCollection(suite.collectionID, suite.schema, querypb.LoadType_LoadCollection) + suite.indexMeta = segments.GenTestIndexMeta(suite.collectionID, suite.schema) + collection := segments.NewCollection(suite.collectionID, suite.schema, suite.indexMeta, querypb.LoadType_LoadCollection) loadMata := &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, CollectionID: suite.collectionID, } - suite.node.manager.Collection.Put(suite.collectionID, collection.Schema(), loadMata) + suite.node.manager.Collection.Put(suite.collectionID, collection.Schema(), suite.indexMeta, loadMata) suite.worker = NewLocalWorker(suite.node) } diff --git a/internal/querynodev2/pipeline/insert_node_test.go b/internal/querynodev2/pipeline/insert_node_test.go index bd41354631..61c3ea22b9 100644 --- a/internal/querynodev2/pipeline/insert_node_test.go +++ b/internal/querynodev2/pipeline/insert_node_test.go @@ -57,7 +57,7 @@ func (suite *InsertNodeSuite) TestBasic() { schema := segments.GenTestCollectionSchema(suite.collectionName, schemapb.DataType_Int64) in := suite.buildInsertNodeMsg(schema) - collection := segments.NewCollection(suite.collectionID, schema, querypb.LoadType_LoadCollection) + collection := segments.NewCollection(suite.collectionID, schema, segments.GenTestIndexMeta(suite.collectionID, schema), querypb.LoadType_LoadCollection) collection.AddPartition(suite.partitionID) //init mock diff --git a/internal/querynodev2/pipeline/pipeline_test.go b/internal/querynodev2/pipeline/pipeline_test.go index bdde26564b..18123754a4 100644 --- a/internal/querynodev2/pipeline/pipeline_test.go +++ b/internal/querynodev2/pipeline/pipeline_test.go @@ -108,7 +108,7 @@ func (suite *PipelineTestSuite) TestBasic() { //init mock // mock collection manager schema := segments.GenTestCollectionSchema(suite.collectionName, schemapb.DataType_Int64) - collection := segments.NewCollection(suite.collectionID, schema, querypb.LoadType_LoadCollection) + collection := segments.NewCollection(suite.collectionID, schema, segments.GenTestIndexMeta(suite.collectionID, schema), querypb.LoadType_LoadCollection) suite.collectionManager.EXPECT().Get(suite.collectionID).Return(collection) // mock mq factory diff --git a/internal/querynodev2/segments/collection.go b/internal/querynodev2/segments/collection.go index 1155cc02cd..ecbeb15c20 100644 --- a/internal/querynodev2/segments/collection.go +++ b/internal/querynodev2/segments/collection.go @@ -25,6 +25,7 @@ package segments import "C" import ( + "github.com/milvus-io/milvus/internal/proto/segcorepb" "sync" "unsafe" @@ -37,7 +38,7 @@ import ( type CollectionManager interface { Get(collectionID int64) *Collection - Put(collectionID int64, schema *schemapb.CollectionSchema, loadMeta *querypb.LoadMetaInfo) + Put(collectionID int64, schema *schemapb.CollectionSchema, meta *segcorepb.CollectionIndexMeta, loadMeta *querypb.LoadMetaInfo) } type collectionManager struct { @@ -58,7 +59,7 @@ func (m *collectionManager) Get(collectionID int64) *Collection { return m.collections[collectionID] } -func (m *collectionManager) Put(collectionID int64, schema *schemapb.CollectionSchema, loadMeta *querypb.LoadMetaInfo) { +func (m *collectionManager) Put(collectionID int64, schema *schemapb.CollectionSchema, meta *segcorepb.CollectionIndexMeta, loadMeta *querypb.LoadMetaInfo) { m.mut.Lock() defer m.mut.Unlock() @@ -66,7 +67,7 @@ func (m *collectionManager) Put(collectionID int64, schema *schemapb.CollectionS return } - collection := NewCollection(collectionID, schema, loadMeta.GetLoadType()) + collection := NewCollection(collectionID, schema, meta, loadMeta.GetLoadType()) collection.AddPartition(loadMeta.GetPartitionIDs()...) m.collections[collectionID] = collection } @@ -118,7 +119,7 @@ func (c *Collection) GetLoadType() querypb.LoadType { } // newCollection returns a new Collection -func NewCollection(collectionID int64, schema *schemapb.CollectionSchema, loadType querypb.LoadType) *Collection { +func NewCollection(collectionID int64, schema *schemapb.CollectionSchema, indexMeta *segcorepb.CollectionIndexMeta, loadType querypb.LoadType) *Collection { /* CCollection NewCollection(const char* schema_proto_blob); @@ -128,6 +129,13 @@ func NewCollection(collectionID int64, schema *schemapb.CollectionSchema, loadTy defer C.free(unsafe.Pointer(cSchemaBlob)) collection := C.NewCollection(cSchemaBlob) + + if indexMeta != nil && len(indexMeta.GetIndexMetas()) > 0 && indexMeta.GetMaxIndexRowCount() > 0 { + indexMetaBlob := proto.MarshalTextString(indexMeta) + cIndexMetaBlob := C.CString(indexMetaBlob) + C.SetIndexMeta(collection, cIndexMetaBlob) + } + return &Collection{ collectionPtr: collection, id: collectionID, diff --git a/internal/querynodev2/segments/manager_test.go b/internal/querynodev2/segments/manager_test.go index 7935aae28a..2eedced660 100644 --- a/internal/querynodev2/segments/manager_test.go +++ b/internal/querynodev2/segments/manager_test.go @@ -37,8 +37,9 @@ func (s *ManagerSuite) SetupTest() { s.mgr = NewSegmentManager() for i, id := range s.segmentIDs { + schema := GenTestCollectionSchema("manager-suite", schemapb.DataType_Int64) segment, err := NewSegment( - NewCollection(s.collectionIDs[i], GenTestCollectionSchema("manager-suite", schemapb.DataType_Int64), querypb.LoadType_LoadCollection), + NewCollection(s.collectionIDs[i], schema, GenTestIndexMeta(s.collectionIDs[i], schema), querypb.LoadType_LoadCollection), id, s.partitionIDs[i], s.collectionIDs[i], diff --git a/internal/querynodev2/segments/mock_collection_manager.go b/internal/querynodev2/segments/mock_collection_manager.go index 878fb4345f..df1f967913 100644 --- a/internal/querynodev2/segments/mock_collection_manager.go +++ b/internal/querynodev2/segments/mock_collection_manager.go @@ -5,6 +5,7 @@ package segments import ( schemapb "github.com/milvus-io/milvus-proto/go-api/schemapb" querypb "github.com/milvus-io/milvus/internal/proto/querypb" + segcorepb "github.com/milvus-io/milvus/internal/proto/segcorepb" mock "github.com/stretchr/testify/mock" ) @@ -61,8 +62,8 @@ func (_c *MockCollectionManager_Get_Call) Return(_a0 *Collection) *MockCollectio } // Put provides a mock function with given fields: collectionID, schema, loadMeta -func (_m *MockCollectionManager) Put(collectionID int64, schema *schemapb.CollectionSchema, loadMeta *querypb.LoadMetaInfo) { - _m.Called(collectionID, schema, loadMeta) +func (_m *MockCollectionManager) Put(collectionID int64, schema *schemapb.CollectionSchema, meta *segcorepb.CollectionIndexMeta, loadMeta *querypb.LoadMetaInfo) { + _m.Called(collectionID, schema, meta, loadMeta) } // MockCollectionManager_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' @@ -74,13 +75,13 @@ type MockCollectionManager_Put_Call struct { // - collectionID int64 // - schema *schemapb.CollectionSchema // - loadMeta *querypb.LoadMetaInfo -func (_e *MockCollectionManager_Expecter) Put(collectionID interface{}, schema interface{}, loadMeta interface{}) *MockCollectionManager_Put_Call { - return &MockCollectionManager_Put_Call{Call: _e.mock.On("Put", collectionID, schema, loadMeta)} +func (_e *MockCollectionManager_Expecter) Put(collectionID interface{}, schema interface{}, meta interface{}, loadMeta interface{}) *MockCollectionManager_Put_Call { + return &MockCollectionManager_Put_Call{Call: _e.mock.On("Put", collectionID, schema, meta, loadMeta)} } -func (_c *MockCollectionManager_Put_Call) Run(run func(collectionID int64, schema *schemapb.CollectionSchema, loadMeta *querypb.LoadMetaInfo)) *MockCollectionManager_Put_Call { +func (_c *MockCollectionManager_Put_Call) Run(run func(collectionID int64, schema *schemapb.CollectionSchema, meta *segcorepb.CollectionIndexMeta, loadMeta *querypb.LoadMetaInfo)) *MockCollectionManager_Put_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int64), args[1].(*schemapb.CollectionSchema), args[2].(*querypb.LoadMetaInfo)) + run(args[0].(int64), args[1].(*schemapb.CollectionSchema), args[2].(*segcorepb.CollectionIndexMeta), args[3].(*querypb.LoadMetaInfo)) }) return _c } diff --git a/internal/querynodev2/segments/mock_data.go b/internal/querynodev2/segments/mock_data.go index 192a8304e6..e55814e305 100644 --- a/internal/querynodev2/segments/mock_data.go +++ b/internal/querynodev2/segments/mock_data.go @@ -39,6 +39,7 @@ import ( "github.com/milvus-io/milvus/internal/proto/internalpb" "github.com/milvus-io/milvus/internal/proto/planpb" "github.com/milvus-io/milvus/internal/proto/querypb" + "github.com/milvus-io/milvus/internal/proto/segcorepb" storage "github.com/milvus-io/milvus/internal/storage" "github.com/milvus-io/milvus/internal/util/indexcgowrapper" "github.com/milvus-io/milvus/pkg/common" @@ -282,6 +283,56 @@ func GenTestCollectionSchema(collectionName string, pkType schemapb.DataType) *s return &schema } +func GenTestIndexMeta(collectionID int64, schema *schemapb.CollectionSchema) *segcorepb.CollectionIndexMeta { + sizePerRecord, err := typeutil.EstimateSizePerRecord(schema) + maxIndexRecordPerSegment := int64(0) + if err != nil || sizePerRecord == 0 { + log.Warn("failed to transfer segment size to collection, because failed to estimate size per record", zap.Error(err)) + } else { + threshold := paramtable.Get().DataCoordCfg.SegmentMaxSize.GetAsFloat() * 1024 * 1024 + proportion := paramtable.Get().DataCoordCfg.SegmentSealProportion.GetAsFloat() + maxIndexRecordPerSegment = int64(threshold * proportion / float64(sizePerRecord)) + } + + fieldIndexMetas := make([]*segcorepb.FieldIndexMeta, 0) + fieldIndexMetas = append(fieldIndexMetas, &segcorepb.FieldIndexMeta{ + CollectionID: collectionID, + FieldID: simpleFloatVecField.id, + IndexName: "querynode-test", + TypeParams: []*commonpb.KeyValuePair{ + { + Key: dimKey, + Value: strconv.Itoa(simpleFloatVecField.dim), + }, + }, + IndexParams: []*commonpb.KeyValuePair{ + { + Key: metricTypeKey, + Value: simpleFloatVecField.metricType, + }, + { + Key: common.IndexTypeKey, + Value: IndexFaissIVFFlat, + }, + { + Key: "nlist", + Value: "128", + }, + }, + IsAutoIndex: false, + UserIndexParams: []*commonpb.KeyValuePair{ + {}, + }, + }) + + indexMeta := segcorepb.CollectionIndexMeta{ + MaxIndexRowCount: maxIndexRecordPerSegment, + IndexMetas: fieldIndexMetas, + } + + return &indexMeta +} + // ---------- unittest util functions ---------- // gen field data func generateBoolArray(numRows int) []bool { diff --git a/internal/querynodev2/segments/plan_test.go b/internal/querynodev2/segments/plan_test.go index 982d2dc55d..0c4c7019ec 100644 --- a/internal/querynodev2/segments/plan_test.go +++ b/internal/querynodev2/segments/plan_test.go @@ -44,7 +44,8 @@ func (suite *PlanSuite) SetupTest() { suite.collectionID = 100 suite.partitionID = 10 suite.segmentID = 1 - suite.collection = NewCollection(suite.collectionID, GenTestCollectionSchema("plan-suite", schemapb.DataType_Int64), querypb.LoadType_LoadCollection) + schema := GenTestCollectionSchema("plan-suite", schemapb.DataType_Int64) + suite.collection = NewCollection(suite.collectionID, schema, GenTestIndexMeta(suite.collectionID, schema), querypb.LoadType_LoadCollection) suite.collection.AddPartition(suite.partitionID) } diff --git a/internal/querynodev2/segments/reduce_test.go b/internal/querynodev2/segments/reduce_test.go index 2eb18adecc..9233da1162 100644 --- a/internal/querynodev2/segments/reduce_test.go +++ b/internal/querynodev2/segments/reduce_test.go @@ -53,8 +53,10 @@ func (suite *ReduceSuite) SetupTest() { suite.collectionID = 100 suite.partitionID = 10 suite.segmentID = 1 + schema := GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64) suite.collection = NewCollection(suite.collectionID, - GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64), + schema, + GenTestIndexMeta(suite.collectionID, schema), querypb.LoadType_LoadCollection, ) suite.segment, err = NewSegment(suite.collection, diff --git a/internal/querynodev2/segments/retrieve_test.go b/internal/querynodev2/segments/retrieve_test.go index f16a3d34ab..a9fd44bb16 100644 --- a/internal/querynodev2/segments/retrieve_test.go +++ b/internal/querynodev2/segments/retrieve_test.go @@ -55,8 +55,11 @@ func (suite *RetrieveSuite) SetupTest() { suite.segmentID = 1 suite.manager = NewManager() + schema := GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64) + indexMeta := GenTestIndexMeta(suite.collectionID, schema) suite.manager.Collection.Put(suite.collectionID, - GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64), + schema, + indexMeta, &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, CollectionID: suite.collectionID, diff --git a/internal/querynodev2/segments/search_test.go b/internal/querynodev2/segments/search_test.go index a14eeb2246..6cc6d354d0 100644 --- a/internal/querynodev2/segments/search_test.go +++ b/internal/querynodev2/segments/search_test.go @@ -51,8 +51,11 @@ func (suite *SearchSuite) SetupTest() { suite.segmentID = 1 suite.manager = NewManager() + schema := GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64) + indexMeta := GenTestIndexMeta(suite.collectionID, schema) suite.manager.Collection.Put(suite.collectionID, - GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64), + schema, + indexMeta, &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, CollectionID: suite.collectionID, diff --git a/internal/querynodev2/segments/segment_loader_test.go b/internal/querynodev2/segments/segment_loader_test.go index 59429ac4d3..8fdb6b84cd 100644 --- a/internal/querynodev2/segments/segment_loader_test.go +++ b/internal/querynodev2/segments/segment_loader_test.go @@ -64,12 +64,13 @@ func (suite *SegmentLoaderSuite) SetupTest() { // Data schema := GenTestCollectionSchema("test", schemapb.DataType_Int64) + indexMeta := GenTestIndexMeta(suite.collectionID, schema) loadMeta := &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, CollectionID: suite.collectionID, PartitionIDs: []int64{suite.partitionID}, } - suite.collectionManager.Put(suite.collectionID, schema, loadMeta) + suite.collectionManager.Put(suite.collectionID, schema, indexMeta, loadMeta) } func (suite *SegmentLoaderSuite) TestLoad() { diff --git a/internal/querynodev2/segments/segment_test.go b/internal/querynodev2/segments/segment_test.go index affb901aa7..5b24aabc24 100644 --- a/internal/querynodev2/segments/segment_test.go +++ b/internal/querynodev2/segments/segment_test.go @@ -35,8 +35,11 @@ func (suite *SegmentSuite) SetupTest() { suite.segmentID = 1 suite.manager = NewManager() + schema := GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64) + indexMeta := GenTestIndexMeta(suite.collectionID, schema) suite.manager.Collection.Put(suite.collectionID, - GenTestCollectionSchema("test-reduce", schemapb.DataType_Int64), + schema, + indexMeta, &querypb.LoadMetaInfo{ LoadType: querypb.LoadType_LoadCollection, CollectionID: suite.collectionID, diff --git a/internal/querynodev2/server.go b/internal/querynodev2/server.go index f939b88614..36ad63a791 100644 --- a/internal/querynodev2/server.go +++ b/internal/querynodev2/server.go @@ -186,10 +186,13 @@ func (node *QueryNode) InitSegcore() { cKnowhereThreadPoolSize := C.uint32_t(paramtable.Get().QueryNodeCfg.KnowhereThreadPoolSize.GetAsUint32()) C.SegcoreSetKnowhereThreadPoolNum(cKnowhereThreadPoolSize) - nlist := C.int64_t(paramtable.Get().QueryNodeCfg.SmallIndexNlist.GetAsInt64()) + enableGrowingIndex := C.bool(paramtable.Get().QueryNodeCfg.EnableGrowingSegmentIndex.GetAsBool()) + C.SegcoreSetEnableGrowingSegmentIndex(enableGrowingIndex) + + nlist := C.int64_t(paramtable.Get().QueryNodeCfg.GrowingIndexNlist.GetAsInt64()) C.SegcoreSetNlist(nlist) - nprobe := C.int64_t(paramtable.Get().QueryNodeCfg.SmallIndexNProbe.GetAsInt64()) + nprobe := C.int64_t(paramtable.Get().QueryNodeCfg.GrowingIndexNProbe.GetAsInt64()) C.SegcoreSetNprobe(nprobe) // override segcore SIMD type diff --git a/internal/querynodev2/services.go b/internal/querynodev2/services.go index 479cdcd3db..8367847bb2 100644 --- a/internal/querynodev2/services.go +++ b/internal/querynodev2/services.go @@ -19,6 +19,7 @@ package querynodev2 import ( "context" "fmt" + "strconv" "sync" @@ -33,6 +34,7 @@ import ( "github.com/milvus-io/milvus/internal/proto/datapb" "github.com/milvus-io/milvus/internal/proto/internalpb" "github.com/milvus-io/milvus/internal/proto/querypb" + "github.com/milvus-io/milvus/internal/proto/segcorepb" "github.com/milvus-io/milvus/internal/querynodev2/collector" "github.com/milvus-io/milvus/internal/querynodev2/delegator" "github.com/milvus-io/milvus/internal/querynodev2/segments" @@ -218,7 +220,32 @@ func (node *QueryNode) WatchDmChannels(ctx context.Context, req *querypb.WatchDm log.Info("channel already subscribed") return util.SuccessStatus(), nil } - node.manager.Collection.Put(req.GetCollectionID(), req.GetSchema(), req.GetLoadMeta()) + + fieldIndexMetas := make([]*segcorepb.FieldIndexMeta, 0) + for _, info := range req.GetIndexInfoList() { + fieldIndexMetas = append(fieldIndexMetas, &segcorepb.FieldIndexMeta{ + CollectionID: info.GetCollectionID(), + FieldID: info.GetFieldID(), + IndexName: info.GetIndexName(), + TypeParams: info.GetTypeParams(), + IndexParams: info.GetIndexParams(), + IsAutoIndex: info.GetIsAutoIndex(), + UserIndexParams: info.GetUserIndexParams(), + }) + } + sizePerRecord, err := typeutil.EstimateSizePerRecord(req.Schema) + maxIndexRecordPerSegment := int64(0) + if err != nil || sizePerRecord == 0 { + log.Warn("failed to transfer segment size to collection, because failed to estimate size per record", zap.Error(err)) + } else { + threshold := paramtable.Get().DataCoordCfg.SegmentMaxSize.GetAsFloat() * 1024 * 1024 + proportion := paramtable.Get().DataCoordCfg.SegmentSealProportion.GetAsFloat() + maxIndexRecordPerSegment = int64(threshold * proportion / float64(sizePerRecord)) + } + node.manager.Collection.Put(req.GetCollectionID(), req.GetSchema(), &segcorepb.CollectionIndexMeta{ + IndexMetas: fieldIndexMetas, + MaxIndexRowCount: maxIndexRecordPerSegment, + }, req.GetLoadMeta()) delegator, err := delegator.NewShardDelegator(req.GetCollectionID(), req.GetReplicaID(), channel.GetChannelName(), req.GetVersion(), node.clusterManager, node.manager, node.tSafeManager, node.loader, node.factory, channel.GetSeekPosition().GetTimestamp()) if err != nil { @@ -391,7 +418,7 @@ func (node *QueryNode) LoadSegments(ctx context.Context, req *querypb.LoadSegmen return node.loadDeltaLogs(ctx, req), nil } - node.manager.Collection.Put(req.GetCollectionID(), req.GetSchema(), req.GetLoadMeta()) + node.manager.Collection.Put(req.GetCollectionID(), req.GetSchema(), nil, req.GetLoadMeta()) // Delegates request to workers if req.GetNeedTransfer() { diff --git a/pkg/util/paramtable/component_param.go b/pkg/util/paramtable/component_param.go index 81ab34d066..fea962fb59 100644 --- a/pkg/util/paramtable/component_param.go +++ b/pkg/util/paramtable/component_param.go @@ -13,7 +13,6 @@ package paramtable import ( "fmt" - "math" "os" "runtime" "strconv" @@ -1389,10 +1388,11 @@ type queryNodeConfig struct { StatsPublishInterval ParamItem `refreshable:"true"` // segcore - KnowhereThreadPoolSize ParamItem `refreshable:"false"` - ChunkRows ParamItem `refreshable:"false"` - SmallIndexNlist ParamItem `refreshable:"false"` - SmallIndexNProbe ParamItem `refreshable:"false"` + KnowhereThreadPoolSize ParamItem `refreshable:"false"` + ChunkRows ParamItem `refreshable:"false"` + EnableGrowingSegmentIndex ParamItem `refreshable:"false"` + GrowingIndexNlist ParamItem `refreshable:"false"` + GrowingIndexNProbe ParamItem `refreshable:"false"` // memory limit LoadMemoryUsageFactor ParamItem `refreshable:"true"` @@ -1499,51 +1499,42 @@ func (p *queryNodeConfig) init(base *BaseTable) { } p.ChunkRows.Init(base.mgr) - p.SmallIndexNlist = ParamItem{ - Key: "queryNode.segcore.smallIndex.nlist", - Version: "2.0.0", - Formatter: func(v string) string { - rows := p.ChunkRows.GetAsInt64() - var defaultNList int64 - for i := int64(0); i < rows; i++ { - if math.Pow(2.0, float64(i)) > math.Sqrt(float64(rows)) { - defaultNList = int64(math.Pow(2, float64(i))) - break - } - } - - nlist := getAsInt64(v) - if nlist == 0 { - nlist = defaultNList - } - if nlist > rows/8 { - return strconv.FormatInt(rows/8, 10) - } - return strconv.FormatInt(nlist, 10) - }, - Doc: "small index nlist, recommend to set sqrt(chunkRows), must smaller than chunkRows/8", - Export: true, + p.EnableGrowingSegmentIndex = ParamItem{ + Key: "queryNode.segcore.growing.enableIndex", + Version: "2.0.0", + DefaultValue: "false", + Doc: "Enable segment growing with index to accelerate vector search.", + Export: true, } - p.SmallIndexNlist.Init(base.mgr) + p.EnableGrowingSegmentIndex.Init(base.mgr) - p.SmallIndexNProbe = ParamItem{ - Key: "queryNode.segcore.smallIndex.nprobe", + p.GrowingIndexNlist = ParamItem{ + Key: "queryNode.segcore.growing.nlist", + Version: "2.0.0", + DefaultValue: "128", + Doc: "growing index nlist, recommend to set sqrt(chunkRows), must smaller than chunkRows/8", + Export: true, + } + p.GrowingIndexNlist.Init(base.mgr) + + p.GrowingIndexNProbe = ParamItem{ + Key: "queryNode.segcore.growing.nprobe", Version: "2.0.0", Formatter: func(v string) string { - defaultNprobe := p.SmallIndexNlist.GetAsInt64() / 16 + defaultNprobe := p.GrowingIndexNlist.GetAsInt64() / 8 nprobe := getAsInt64(v) if nprobe == 0 { nprobe = defaultNprobe } - if nprobe > p.SmallIndexNlist.GetAsInt64() { - return p.SmallIndexNlist.GetValue() + if nprobe > p.GrowingIndexNlist.GetAsInt64() { + return p.GrowingIndexNlist.GetValue() } return strconv.FormatInt(nprobe, 10) }, Doc: "nprobe to search small index, based on your accuracy requirement, must smaller than nlist", Export: true, } - p.SmallIndexNProbe.Init(base.mgr) + p.GrowingIndexNProbe.Init(base.mgr) p.LoadMemoryUsageFactor = ParamItem{ Key: "queryNode.loadMemoryUsageFactor", diff --git a/pkg/util/paramtable/component_param_test.go b/pkg/util/paramtable/component_param_test.go index 5950ef3d6c..f9725c2005 100644 --- a/pkg/util/paramtable/component_param_test.go +++ b/pkg/util/paramtable/component_param_test.go @@ -290,10 +290,10 @@ func TestComponentParam(t *testing.T) { chunkRows := Params.ChunkRows.GetAsInt64() assert.Equal(t, int64(1024), chunkRows) - nlist := Params.SmallIndexNlist.GetAsInt64() + nlist := Params.GrowingIndexNlist.GetAsInt64() assert.Equal(t, int64(128), nlist) - nprobe := Params.SmallIndexNProbe.GetAsInt64() + nprobe := Params.GrowingIndexNProbe.GetAsInt64() assert.Equal(t, int64(16), nprobe) assert.Equal(t, true, Params.GroupEnabled.GetAsBool()) @@ -312,24 +312,25 @@ func TestComponentParam(t *testing.T) { chunkRows = Params.ChunkRows.GetAsInt64() assert.Equal(t, int64(8192), chunkRows) - nlist = Params.SmallIndexNlist.GetAsInt64() + enableGrowingIndex := Params.EnableGrowingSegmentIndex.GetAsBool() + assert.Equal(t, false, enableGrowingIndex) + + params.Save("queryNode.segcore.growing.enableIndex", "true") + enableGrowingIndex = Params.EnableGrowingSegmentIndex.GetAsBool() + assert.Equal(t, true, enableGrowingIndex) + + nlist = Params.GrowingIndexNlist.GetAsInt64() assert.Equal(t, int64(128), nlist) - nprobe = Params.SmallIndexNProbe.GetAsInt64() - assert.Equal(t, int64(8), nprobe) + nprobe = Params.GrowingIndexNProbe.GetAsInt64() + assert.Equal(t, int64(16), nprobe) - params.Remove("queryNode.segcore.smallIndex.nlist") - params.Remove("queryNode.segcore.smallIndex.nprobe") + params.Remove("queryNode.segcore.growing.nlist") + params.Remove("queryNode.segcore.growing.nprobe") params.Save("queryNode.segcore.chunkRows", "64") chunkRows = Params.ChunkRows.GetAsInt64() assert.Equal(t, int64(1024), chunkRows) - nlist = Params.SmallIndexNlist.GetAsInt64() - assert.Equal(t, int64(64), nlist) - - nprobe = Params.SmallIndexNProbe.GetAsInt64() - assert.Equal(t, int64(4), nprobe) - params.Save("queryNode.gracefulStopTimeout", "100") gracefulStopTimeout := Params.GracefulStopTimeout assert.Equal(t, int64(100), gracefulStopTimeout.GetAsInt64())