Support to get real row count of segment (#18115)

Signed-off-by: xaxys <zheng.guan@zilliz.com>
pull/18301/head
Jeng.Gwan 2022-07-18 09:58:28 +08:00 committed by GitHub
parent c4f32d44b5
commit 638f6c36e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 4220 additions and 1388 deletions

View File

@ -45,7 +45,7 @@ class SegmentGrowing : public SegmentInternalInterface {
// Delete(int64_t reserved_offset, int64_t size, const int64_t* row_ids, const Timestamp* timestamps) = 0;
public:
virtual ssize_t
virtual int64_t
get_deleted_count() const = 0;
};

View File

@ -131,9 +131,9 @@ class SegmentGrowingImpl : public SegmentGrowing {
return insert_record_.ack_responder_.GetAck();
}
ssize_t
int64_t
get_deleted_count() const override {
return 0;
return deleted_record_.ack_responder_.GetAck();
}
int64_t

View File

@ -105,4 +105,14 @@ SegmentInternalInterface::Retrieve(const query::RetrievePlan* plan, Timestamp ti
}
return results;
}
int64_t
SegmentInternalInterface::get_real_count() const {
auto insert_cnt = get_row_count();
BitsetType bitset_holder;
bitset_holder.resize(insert_cnt, false);
mask_with_delete(bitset_holder, insert_cnt, MAX_TIMESTAMP);
return bitset_holder.size() - bitset_holder.count();
}
} // namespace milvus::segcore

View File

@ -61,6 +61,12 @@ class SegmentInterface {
virtual const Schema&
get_schema() const = 0;
virtual int64_t
get_deleted_count() const = 0;
virtual int64_t
get_real_count() const = 0;
virtual int64_t
PreDelete(int64_t size) = 0;
@ -118,6 +124,9 @@ class SegmentInternalInterface : public SegmentInterface {
virtual std::string
debug() const = 0;
int64_t
get_real_count() const override;
public:
virtual void
vector_search(int64_t vec_count,

View File

@ -322,6 +322,12 @@ SegmentSealedImpl::get_row_count() const {
return row_count_opt_.value_or(0);
}
int64_t
SegmentSealedImpl::get_deleted_count() const {
std::shared_lock lck(mutex_);
return deleted_record_.ack_responder_.GetAck();
}
const Schema&
SegmentSealedImpl::get_schema() const {
return *schema_;

View File

@ -62,6 +62,9 @@ class SegmentSealedImpl : public SegmentSealed {
int64_t
get_row_count() const override;
int64_t
get_deleted_count() const override;
const Schema&
get_schema() const override;

View File

@ -125,11 +125,19 @@ GetRowCount(CSegmentInterface c_segment) {
// TODO: segmentInterface implement get_deleted_count()
int64_t
GetDeletedCount(CSegmentInterface c_segment) {
auto segment = (milvus::segcore::SegmentGrowing*)c_segment;
auto segment = reinterpret_cast<milvus::segcore::SegmentInterface*>(c_segment);
auto deleted_count = segment->get_deleted_count();
return deleted_count;
}
int64_t
GetRealCount(CSegmentInterface c_segment) {
// not accurate, pk may exist in deleted record and not in insert record.
// return GetRowCount(c_segment) - GetDeletedCount(c_segment);
auto segment = reinterpret_cast<milvus::segcore::SegmentInterface*>(c_segment);
return segment->get_real_count();
}
////////////////////////////// interfaces for growing segment //////////////////////////////
CStatus
Insert(CSegmentInterface c_segment,

View File

@ -60,6 +60,9 @@ GetRowCount(CSegmentInterface c_segment);
int64_t
GetDeletedCount(CSegmentInterface c_segment);
int64_t
GetRealCount(CSegmentInterface c_segment);
////////////////////////////// interfaces for growing segment //////////////////////////////
CStatus
Insert(CSegmentInterface c_segment,

View File

@ -26,6 +26,7 @@ set(MILVUS_TEST_FILES
test_conf_adapter_mgr.cpp
test_c_api.cpp
test_expr.cpp
test_growing.cpp
test_indexing.cpp
test_index_c_api.cpp
test_index_wrapper.cpp

View File

@ -174,7 +174,8 @@ generate_collection_schema(std::string metric_type, int dim, bool is_binary) {
}
VecIndexPtr
generate_index(void* raw_data, knowhere::Config conf, int64_t dim, int64_t topK, int64_t N, knowhere::IndexType index_type) {
generate_index(
void* raw_data, knowhere::Config conf, int64_t dim, int64_t topK, int64_t N, knowhere::IndexType index_type) {
auto indexing = knowhere::VecIndexFactory::GetInstance().CreateVecIndex(index_type, knowhere::IndexMode::MODE_CPU);
auto database = knowhere::GenDataset(N, dim, raw_data);
@ -1007,7 +1008,7 @@ TEST(CApiTest, GetDeletedCountTest) {
// TODO: assert(deleted_count == len(delete_row_ids))
auto deleted_count = GetDeletedCount(segment);
assert(deleted_count == 0);
assert(deleted_count == delete_row_ids.size());
DeleteCollection(collection);
DeleteSegment(segment);
@ -1036,6 +1037,42 @@ TEST(CApiTest, GetRowCountTest) {
DeleteSegment(segment);
}
TEST(CApiTest, GetRealCount) {
auto collection = NewCollection(get_default_schema_config());
auto segment = NewSegment(collection, Growing, -1);
auto schema = ((milvus::segcore::Collection*)collection)->get_schema();
int N = 10000;
auto dataset = DataGen(schema, N);
int64_t offset;
PreInsert(segment, N, &offset);
auto insert_data = serialize(dataset.raw_);
auto res = Insert(segment, offset, N, dataset.row_ids_.data(), dataset.timestamps_.data(), insert_data.data(),
insert_data.size());
assert(res.error_code == Success);
auto pks = dataset.get_col<int64_t>(schema->get_primary_field_id().value());
std::vector<int64_t> delete_row_ids(pks.begin(), pks.begin() + 3);
auto ids = std::make_unique<IdArray>();
ids->mutable_int_id()->mutable_data()->Add(delete_row_ids.begin(), delete_row_ids.end());
auto delete_data = serialize(ids.get());
uint64_t delete_timestamps[] = {dataset.timestamps_[N - 1] + 1, dataset.timestamps_[N - 1] + 2,
dataset.timestamps_[N - 1] + 3};
auto del_offset = PreDelete(segment, 3);
auto del_res = Delete(segment, del_offset, 3, delete_data.data(), delete_data.size(), delete_timestamps);
assert(del_res.error_code == Success);
auto real_count = GetRealCount(segment);
assert(real_count == N - delete_row_ids.size());
DeleteCollection(collection);
DeleteSegment(segment);
}
// TEST(CApiTest, SchemaTest) {
// std::string schema_string =
// "id: 6873737669791618215\nname: \"collection0\"\nschema: \u003c\n "
@ -1389,16 +1426,14 @@ TEST(CApiTest, LoadIndexInfo) {
auto N = 1024 * 10;
auto [raw_data, timestamps, uids] = generate_data(N);
auto indexing = std::make_shared<knowhere::IVFPQ>();
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 4},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 4},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto database = knowhere::GenDataset(N, DIM, raw_data.data());
indexing->Train(database, conf);
@ -1434,16 +1469,14 @@ TEST(CApiTest, LoadIndex_Search) {
auto num_query = 100;
auto [raw_data, timestamps, uids] = generate_data(N);
auto indexing = std::make_shared<knowhere::IVFPQ>();
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 4},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 4},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto database = knowhere::GenDataset(N, DIM, raw_data.data());
indexing->Train(database, conf);
@ -1538,16 +1571,14 @@ TEST(CApiTest, Indexing_Without_Predicate) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
// gen query dataset
@ -1665,16 +1696,14 @@ TEST(CApiTest, Indexing_Expr_Without_Predicate) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
// gen query dataset
@ -1809,15 +1838,14 @@ TEST(CApiTest, Indexing_With_float_Predicate_Range) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
@ -1967,16 +1995,14 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Range) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
@ -2110,16 +2136,14 @@ TEST(CApiTest, Indexing_With_float_Predicate_Term) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
@ -2262,16 +2286,14 @@ TEST(CApiTest, Indexing_Expr_With_float_Predicate_Term) {
assert(res_before_load_index.error_code == Success);
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
@ -3053,16 +3075,14 @@ TEST(CApiTest, SealedSegment_search_float_Predicate_Range) {
Timestamp time = 10000000;
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);
@ -3350,16 +3370,14 @@ TEST(CApiTest, SealedSegment_search_float_With_Expr_Predicate_Range) {
Timestamp time = 10000000;
// load index to segment
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, 100},
{knowhere::indexparam::NPROBE, 10},
{knowhere::indexparam::M, 4},
{knowhere::indexparam::NBITS, 8},
{knowhere::meta::DEVICE_ID, 0}};
auto indexing = generate_index(vec_col.data(), conf, DIM, TOPK, N, IndexEnum::INDEX_FAISS_IVFPQ);

View File

@ -0,0 +1,85 @@
// 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 <gtest/gtest.h>
#include "segcore/SegmentGrowing.h"
#include "segcore/SegmentGrowingImpl.h"
#include "pb/schema.pb.h"
#include "test_utils/DataGen.h"
using namespace milvus::segcore;
using namespace milvus;
namespace pb = milvus::proto;
TEST(Growing, DeleteCount) {
auto schema = std::make_shared<Schema>();
auto pk = schema->AddDebugField("pk", DataType::INT64);
schema->set_primary_field_id(pk);
auto segment = CreateGrowingSegment(schema);
int64_t c = 10;
auto offset = segment->PreDelete(c);
ASSERT_EQ(offset, 0);
Timestamp begin_ts = 100;
auto tss = GenTss(c, begin_ts);
auto pks = GenPKs(c, 0);
auto status = segment->Delete(offset, c, pks.get(), tss.data());
ASSERT_TRUE(status.ok());
auto cnt = segment->get_deleted_count();
ASSERT_EQ(cnt, c);
}
TEST(Growing, RealCount) {
auto schema = std::make_shared<Schema>();
auto pk = schema->AddDebugField("pk", DataType::INT64);
schema->set_primary_field_id(pk);
auto segment = CreateGrowingSegment(schema);
int64_t c = 10;
auto offset = segment->PreInsert(c);
ASSERT_EQ(offset, 0);
auto dataset = DataGen(schema, c);
auto pks = dataset.get_col<int64_t>(pk);
segment->Insert(offset, c, dataset.row_ids_.data(), dataset.timestamps_.data(), dataset.raw_);
// no delete.
ASSERT_EQ(c, segment->get_real_count());
// delete half.
auto half = c / 2;
auto del_offset1 = segment->PreDelete(half);
ASSERT_EQ(del_offset1, 0);
auto del_ids1 = GenPKs(pks.begin(), pks.begin() + half);
auto del_tss1 = GenTss(half, c);
auto status = segment->Delete(del_offset1, half, del_ids1.get(), del_tss1.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(c - half, segment->get_real_count());
// delete duplicate.
auto del_offset2 = segment->PreDelete(half);
ASSERT_EQ(del_offset2, half);
auto del_tss2 = GenTss(half, c + half);
status = segment->Delete(del_offset2, half, del_ids1.get(), del_tss2.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(c - half, segment->get_real_count());
// delete all.
auto del_offset3 = segment->PreDelete(c);
ASSERT_EQ(del_offset3, half * 2);
auto del_ids3 = GenPKs(pks.begin(), pks.end());
auto del_tss3 = GenTss(c, c + half * 2);
status = segment->Delete(del_offset3, c, del_ids3.get(), del_tss3.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(0, segment->get_real_count());
}

View File

@ -221,14 +221,12 @@ TEST(Indexing, IVFFlat) {
auto [raw_data, timestamps, uids] = generate_data<DIM>(N);
std::cout << "generate data: " << timer.get_step_seconds() << " seconds" << std::endl;
auto indexing = std::make_shared<knowhere::IVF>();
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, NLIST},
{knowhere::indexparam::NPROBE, NPROBE},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, NLIST},
{knowhere::indexparam::NPROBE, NPROBE},
{knowhere::meta::DEVICE_ID, 0}};
auto database = knowhere::GenDataset(N, DIM, raw_data.data());
std::cout << "init ivf " << timer.get_step_seconds() << " seconds" << std::endl;
@ -263,14 +261,12 @@ TEST(Indexing, IVFFlatNM) {
auto [raw_data, timestamps, uids] = generate_data<DIM>(N);
std::cout << "generate data: " << timer.get_step_seconds() << " seconds" << std::endl;
auto indexing = std::make_shared<knowhere::IVF_NM>();
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, NLIST},
{knowhere::indexparam::NPROBE, NPROBE},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, DIM},
{knowhere::meta::TOPK, TOPK},
{knowhere::indexparam::NLIST, NLIST},
{knowhere::indexparam::NPROBE, NPROBE},
{knowhere::meta::DEVICE_ID, 0}};
auto database = knowhere::GenDataset(N, DIM, raw_data.data());
std::cout << "init ivf_nm " << timer.get_step_seconds() << " seconds" << std::endl;

View File

@ -667,4 +667,66 @@ TEST(Sealed, BF_Overflow) {
for (int i = 0; i < num_queries; ++i) {
EXPECT_EQ(ves[0].first, -1);
}
}
}
TEST(Sealed, DeleteCount) {
auto schema = std::make_shared<Schema>();
auto pk = schema->AddDebugField("pk", DataType::INT64);
schema->set_primary_field_id(pk);
auto segment = CreateSealedSegment(schema);
int64_t c = 10;
auto offset = segment->PreDelete(c);
ASSERT_EQ(offset, 0);
Timestamp begin_ts = 100;
auto tss = GenTss(c, begin_ts);
auto pks = GenPKs(c, 0);
auto status = segment->Delete(offset, c, pks.get(), tss.data());
ASSERT_TRUE(status.ok());
auto cnt = segment->get_deleted_count();
ASSERT_EQ(cnt, c);
}
TEST(Sealed, RealCount) {
auto schema = std::make_shared<Schema>();
auto pk = schema->AddDebugField("pk", DataType::INT64);
schema->set_primary_field_id(pk);
auto segment = CreateSealedSegment(schema);
int64_t c = 10;
auto dataset = DataGen(schema, c);
auto pks = dataset.get_col<int64_t>(pk);
SealedLoadFieldData(dataset, *segment);
// no delete.
ASSERT_EQ(c, segment->get_real_count());
// delete half.
auto half = c / 2;
auto del_offset1 = segment->PreDelete(half);
ASSERT_EQ(del_offset1, 0);
auto del_ids1 = GenPKs(pks.begin(), pks.begin() + half);
auto del_tss1 = GenTss(half, c);
auto status = segment->Delete(del_offset1, half, del_ids1.get(), del_tss1.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(c - half, segment->get_real_count());
// delete duplicate.
auto del_offset2 = segment->PreDelete(half);
ASSERT_EQ(del_offset2, half);
auto del_tss2 = GenTss(half, c + half);
status = segment->Delete(del_offset2, half, del_ids1.get(), del_tss2.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(c - half, segment->get_real_count());
// delete all.
auto del_offset3 = segment->PreDelete(c);
ASSERT_EQ(del_offset3, half * 2);
auto del_ids3 = GenPKs(pks.begin(), pks.end());
auto del_tss3 = GenTss(c, c + half * 2);
status = segment->Delete(del_offset3, c, del_ids3.get(), del_tss3.data());
ASSERT_TRUE(status.ok());
ASSERT_EQ(0, segment->get_real_count());
}

View File

@ -431,12 +431,10 @@ SealedCreator(SchemaPtr schema, const GeneratedData& dataset) {
inline knowhere::VecIndexPtr
GenVecIndexing(int64_t N, int64_t dim, const float* vec) {
// {knowhere::IndexParams::nprobe, 10},
auto conf = knowhere::Config{
{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, dim},
{knowhere::indexparam::NLIST, 1024},
{knowhere::meta::DEVICE_ID, 0}
};
auto conf = knowhere::Config{{knowhere::meta::METRIC_TYPE, knowhere::metric::L2},
{knowhere::meta::DIM, dim},
{knowhere::indexparam::NLIST, 1024},
{knowhere::meta::DEVICE_ID, 0}};
auto database = knowhere::GenDataset(N, dim, vec);
auto indexing = std::make_shared<knowhere::IVF>();
indexing->Train(database, conf);
@ -474,4 +472,39 @@ translate_text_plan_to_binary_plan(const char* text_plan) {
return ret;
}
inline auto
GenTss(int64_t num, int64_t begin_ts) {
std::vector<Timestamp> tss(num, 0);
std::iota(tss.begin(), tss.end(), begin_ts);
return tss;
}
inline auto
GenPKs(int64_t num, int64_t begin_pk) {
auto arr = std::make_unique<milvus::proto::schema::LongArray>();
for (int64_t i = 0; i < num; i++) {
arr->add_data(begin_pk + i);
}
auto ids = std::make_shared<IdArray>();
ids->set_allocated_int_id(arr.release());
return ids;
}
template <typename Iter>
inline auto
GenPKs(const Iter begin, const Iter end) {
auto arr = std::make_unique<milvus::proto::schema::LongArray>();
for (auto it = begin; it != end; it++) {
arr->add_data(*it);
}
auto ids = std::make_shared<IdArray>();
ids->set_allocated_int_id(arr.release());
return ids;
}
inline auto
GenPKs(const std::vector<int64_t>& pks) {
return GenPKs(pks.begin(), pks.end());
}
} // namespace milvus::segcore

View File

@ -468,7 +468,7 @@ func TestGetPartitionStatistics(t *testing.T) {
req := &datapb.GetPartitionStatisticsRequest{
CollectionID: 0,
PartitionID: 0,
PartitionIDs: []int64{0},
}
resp, err := svr.GetPartitionStatistics(context.Background(), req)
assert.Nil(t, err)

View File

@ -264,7 +264,8 @@ func (s *Server) GetCollectionStatistics(ctx context.Context, req *datapb.GetCol
return resp, nil
}
// GetPartitionStatistics returns statistics for parition
// GetPartitionStatistics returns statistics for partition
// if partID is empty, return statistics for all partitions of the collection
// for now only row count is returned
func (s *Server) GetPartitionStatistics(ctx context.Context, req *datapb.GetPartitionStatisticsRequest) (*datapb.GetPartitionStatisticsResponse, error) {
resp := &datapb.GetPartitionStatisticsResponse{
@ -276,9 +277,17 @@ func (s *Server) GetPartitionStatistics(ctx context.Context, req *datapb.GetPart
resp.Status.Reason = serverNotServingErrMsg
return resp, nil
}
nums := s.meta.GetNumRowsOfPartition(req.CollectionID, req.PartitionID)
nums := int64(0)
if len(req.GetPartitionIDs()) == 0 {
nums = s.meta.GetNumRowsOfCollection(req.CollectionID)
}
for _, partID := range req.GetPartitionIDs() {
num := s.meta.GetNumRowsOfPartition(req.CollectionID, partID)
nums += num
}
resp.Status.ErrorCode = commonpb.ErrorCode_Success
resp.Stats = append(resp.Stats, &commonpb.KeyValuePair{Key: "row_count", Value: strconv.FormatInt(nums, 10)})
logutil.Logger(ctx).Debug("success to get partition statistics", zap.Any("response", resp))
return resp, nil
}

View File

@ -291,3 +291,16 @@ func (c *Client) GetMetrics(ctx context.Context, req *milvuspb.GetMetricsRequest
}
return ret.(*milvuspb.GetMetricsResponse), err
}
func (c *Client) GetStatistics(ctx context.Context, request *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
ret, err := c.grpcClient.Call(ctx, func(client interface{}) (interface{}, error) {
if !funcutil.CheckCtxValid(ctx) {
return nil, ctx.Err()
}
return client.(querypb.QueryNodeClient).GetStatistics(ctx, request)
})
if err != nil || ret == nil {
return nil, err
}
return ret.(*internalpb.GetStatisticsResponse), err
}

View File

@ -101,6 +101,9 @@ func Test_NewClient(t *testing.T) {
r16, err := client.SyncReplicaSegments(ctx, nil)
retCheck(retNotNil, r16, err)
r17, err := client.GetStatistics(ctx, nil)
retCheck(retNotNil, r17, err)
}
client.grpcClient = &mock.GRPCClientBase{

View File

@ -67,6 +67,10 @@ type Server struct {
closer io.Closer
}
func (s *Server) GetStatistics(ctx context.Context, request *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return s.querynode.GetStatistics(ctx, request)
}
// NewServer create a new QueryNode grpc server.
func NewServer(ctx context.Context, factory dependency.Factory) (*Server, error) {
ctx1, cancel := context.WithCancel(ctx)

View File

@ -44,6 +44,7 @@ type MockQueryNode struct {
strResp *milvuspb.StringResponse
infoResp *querypb.GetSegmentInfoResponse
metricResp *milvuspb.GetMetricsResponse
StatsResp *internalpb.GetStatisticsResponse
searchResp *internalpb.SearchResults
queryResp *internalpb.RetrieveResults
}
@ -108,6 +109,10 @@ func (m *MockQueryNode) GetMetrics(ctx context.Context, req *milvuspb.GetMetrics
return m.metricResp, m.err
}
func (m *MockQueryNode) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return m.StatsResp, m.err
}
func (m *MockQueryNode) Search(ctx context.Context, req *querypb.SearchRequest) (*internalpb.SearchResults, error) {
return m.searchResp, m.err
}

View File

@ -174,7 +174,7 @@ message GetPartitionStatisticsRequest{
common.MsgBase base = 1;
int64 dbID = 2;
int64 collectionID = 3;
int64 partitionID = 4;
repeated int64 partitionIDs = 4;
}
message GetPartitionStatisticsResponse {

View File

@ -1003,7 +1003,7 @@ type GetPartitionStatisticsRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
DbID int64 `protobuf:"varint,2,opt,name=dbID,proto3" json:"dbID,omitempty"`
CollectionID int64 `protobuf:"varint,3,opt,name=collectionID,proto3" json:"collectionID,omitempty"`
PartitionID int64 `protobuf:"varint,4,opt,name=partitionID,proto3" json:"partitionID,omitempty"`
PartitionIDs []int64 `protobuf:"varint,4,rep,packed,name=partitionIDs,proto3" json:"partitionIDs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1055,11 +1055,11 @@ func (m *GetPartitionStatisticsRequest) GetCollectionID() int64 {
return 0
}
func (m *GetPartitionStatisticsRequest) GetPartitionID() int64 {
func (m *GetPartitionStatisticsRequest) GetPartitionIDs() []int64 {
if m != nil {
return m.PartitionID
return m.PartitionIDs
}
return 0
return nil
}
type GetPartitionStatisticsResponse struct {
@ -4189,241 +4189,241 @@ func init() {
func init() { proto.RegisterFile("data_coord.proto", fileDescriptor_82cd95f524594f49) }
var fileDescriptor_82cd95f524594f49 = []byte{
// 3734 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1b, 0x5b, 0x6f, 0x1c, 0x57,
0x39, 0xb3, 0x37, 0xef, 0x7e, 0x7b, 0xf1, 0xfa, 0x24, 0x75, 0x36, 0x9b, 0xc4, 0x49, 0x26, 0x4d,
0x9a, 0xa6, 0x69, 0xd2, 0x3a, 0x54, 0xad, 0xe8, 0x4d, 0x71, 0x9c, 0x38, 0x2b, 0xec, 0xe0, 0x8c,
0x9d, 0x06, 0x51, 0xc4, 0x6a, 0xbc, 0x73, 0xbc, 0x9e, 0x7a, 0x67, 0x66, 0x33, 0x33, 0x1b, 0xc7,
0x7d, 0x69, 0x45, 0x25, 0xa4, 0x22, 0x44, 0x91, 0x10, 0x12, 0x48, 0x20, 0x21, 0x9e, 0xb8, 0xbc,
0x20, 0x55, 0x3c, 0x00, 0xea, 0x7b, 0x05, 0x0f, 0x88, 0x67, 0x7e, 0x00, 0xbc, 0xc0, 0x6f, 0x40,
0xe7, 0x32, 0x67, 0xee, 0xbb, 0xe3, 0x75, 0xd2, 0xf0, 0xb6, 0xe7, 0x9b, 0xef, 0x7c, 0xe7, 0x3b,
0xdf, 0xf9, 0xee, 0xe7, 0x2c, 0x34, 0x35, 0xd5, 0x55, 0xbb, 0x3d, 0xcb, 0xb2, 0xb5, 0xab, 0x43,
0xdb, 0x72, 0x2d, 0x34, 0x67, 0xe8, 0x83, 0x47, 0x23, 0x87, 0x8d, 0xae, 0x92, 0xcf, 0xed, 0x5a,
0xcf, 0x32, 0x0c, 0xcb, 0x64, 0xa0, 0x76, 0x43, 0x37, 0x5d, 0x6c, 0x9b, 0xea, 0x80, 0x8f, 0x6b,
0xc1, 0x09, 0xed, 0x9a, 0xd3, 0xdb, 0xc1, 0x86, 0xca, 0x46, 0xf2, 0x0c, 0x14, 0x6f, 0x19, 0x43,
0x77, 0x5f, 0xfe, 0x99, 0x04, 0xb5, 0xdb, 0x83, 0x91, 0xb3, 0xa3, 0xe0, 0x87, 0x23, 0xec, 0xb8,
0xe8, 0x15, 0x28, 0x6c, 0xa9, 0x0e, 0x6e, 0x49, 0x67, 0xa5, 0x4b, 0xd5, 0xc5, 0x53, 0x57, 0x43,
0xab, 0xf2, 0xf5, 0xd6, 0x9c, 0xfe, 0x92, 0xea, 0x60, 0x85, 0x62, 0x22, 0x04, 0x05, 0x6d, 0xab,
0xb3, 0xdc, 0xca, 0x9d, 0x95, 0x2e, 0xe5, 0x15, 0xfa, 0x1b, 0x2d, 0x00, 0x38, 0xb8, 0x6f, 0x60,
0xd3, 0xed, 0x2c, 0x3b, 0xad, 0xfc, 0xd9, 0xfc, 0xa5, 0xbc, 0x12, 0x80, 0x20, 0x19, 0x6a, 0x3d,
0x6b, 0x30, 0xc0, 0x3d, 0x57, 0xb7, 0xcc, 0xce, 0x72, 0xab, 0x40, 0xe7, 0x86, 0x60, 0xf2, 0x2f,
0x24, 0xa8, 0x73, 0xd6, 0x9c, 0xa1, 0x65, 0x3a, 0x18, 0x5d, 0x87, 0x92, 0xe3, 0xaa, 0xee, 0xc8,
0xe1, 0xdc, 0x9d, 0x4c, 0xe4, 0x6e, 0x83, 0xa2, 0x28, 0x1c, 0x35, 0x91, 0xbd, 0xe8, 0xf2, 0xf9,
0xf8, 0xf2, 0x91, 0x2d, 0x14, 0xa2, 0x5b, 0x90, 0xff, 0x21, 0x41, 0x73, 0xc3, 0x1b, 0x7a, 0xd2,
0x3b, 0x06, 0xc5, 0x9e, 0x35, 0x32, 0x5d, 0xca, 0x60, 0x5d, 0x61, 0x03, 0x74, 0x0e, 0x6a, 0xbd,
0x1d, 0xd5, 0x34, 0xf1, 0xa0, 0x6b, 0xaa, 0x06, 0xa6, 0xac, 0x54, 0x94, 0x2a, 0x87, 0xdd, 0x55,
0x0d, 0x9c, 0x89, 0xa3, 0xb3, 0x50, 0x1d, 0xaa, 0xb6, 0xab, 0x87, 0x64, 0x16, 0x04, 0xa1, 0x36,
0x94, 0x75, 0xa7, 0x63, 0x0c, 0x2d, 0xdb, 0x6d, 0x15, 0xcf, 0x4a, 0x97, 0xca, 0x8a, 0x18, 0x93,
0x15, 0x74, 0xfa, 0x6b, 0x53, 0x75, 0x76, 0x3b, 0xcb, 0xad, 0x12, 0x5b, 0x21, 0x08, 0x93, 0x7f,
0x25, 0xc1, 0xfc, 0x0d, 0xc7, 0xd1, 0xfb, 0x66, 0x6c, 0x67, 0xf3, 0x50, 0x32, 0x2d, 0x0d, 0x77,
0x96, 0xe9, 0xd6, 0xf2, 0x0a, 0x1f, 0xa1, 0x93, 0x50, 0x19, 0x62, 0x6c, 0x77, 0x6d, 0x6b, 0xe0,
0x6d, 0xac, 0x4c, 0x00, 0x8a, 0x35, 0xc0, 0xe8, 0x1e, 0xcc, 0x39, 0x11, 0x42, 0x4c, 0x1b, 0xaa,
0x8b, 0xe7, 0xaf, 0xc6, 0xf4, 0xf9, 0x6a, 0x74, 0x51, 0x25, 0x3e, 0x5b, 0xfe, 0x38, 0x07, 0x47,
0x05, 0x1e, 0xe3, 0x95, 0xfc, 0x26, 0x92, 0x77, 0x70, 0x5f, 0xb0, 0xc7, 0x06, 0x59, 0x24, 0x2f,
0x8e, 0x2c, 0x1f, 0x3c, 0xb2, 0x0c, 0x0a, 0x1a, 0x3d, 0x8f, 0x62, 0xfc, 0x3c, 0xce, 0x40, 0x15,
0x3f, 0x1e, 0xea, 0x36, 0xee, 0xba, 0xba, 0x81, 0xa9, 0xc8, 0x0b, 0x0a, 0x30, 0xd0, 0xa6, 0x6e,
0x04, 0x35, 0x7a, 0x26, 0xb3, 0x46, 0xcb, 0xbf, 0x96, 0xe0, 0x78, 0xec, 0x94, 0xb8, 0x89, 0x28,
0xd0, 0xa4, 0x3b, 0xf7, 0x25, 0x43, 0x8c, 0x85, 0x08, 0xfc, 0xe2, 0x38, 0x81, 0xfb, 0xe8, 0x4a,
0x6c, 0x7e, 0x80, 0xc9, 0x5c, 0x76, 0x26, 0x77, 0xe1, 0xf8, 0x0a, 0x76, 0xf9, 0x02, 0xe4, 0x1b,
0x76, 0xa6, 0x77, 0x31, 0x61, 0x5b, 0xcc, 0xc5, 0x6c, 0xf1, 0x0f, 0x39, 0x61, 0x8b, 0x74, 0xa9,
0x8e, 0xb9, 0x6d, 0xa1, 0x53, 0x50, 0x11, 0x28, 0x5c, 0x2b, 0x7c, 0x00, 0x7a, 0x1d, 0x8a, 0x84,
0x53, 0xa6, 0x12, 0x8d, 0xc5, 0x73, 0xc9, 0x7b, 0x0a, 0xd0, 0x54, 0x18, 0x3e, 0xea, 0x40, 0xc3,
0x71, 0x55, 0xdb, 0xed, 0x0e, 0x2d, 0x87, 0x9e, 0x33, 0x55, 0x9c, 0xea, 0xa2, 0x1c, 0xa6, 0x20,
0x9c, 0xf1, 0x9a, 0xd3, 0x5f, 0xe7, 0x98, 0x4a, 0x9d, 0xce, 0xf4, 0x86, 0xe8, 0x16, 0xd4, 0xb0,
0xa9, 0xf9, 0x84, 0x0a, 0x99, 0x09, 0x55, 0xb1, 0xa9, 0x09, 0x32, 0xfe, 0xf9, 0x14, 0xb3, 0x9f,
0xcf, 0x0f, 0x25, 0x68, 0xc5, 0x0f, 0xe8, 0x30, 0x8e, 0xf6, 0x4d, 0x36, 0x09, 0xb3, 0x03, 0x1a,
0x6b, 0xe1, 0xe2, 0x90, 0x14, 0x3e, 0x45, 0xfe, 0xa9, 0x04, 0xcf, 0xf9, 0xec, 0xd0, 0x4f, 0x4f,
0x4b, 0x5b, 0xd0, 0x65, 0x68, 0xea, 0x66, 0x6f, 0x30, 0xd2, 0xf0, 0x7d, 0xf3, 0x0e, 0x56, 0x07,
0xee, 0xce, 0x3e, 0x3d, 0xc3, 0xb2, 0x12, 0x83, 0xcb, 0x9f, 0x48, 0x30, 0x1f, 0xe5, 0xeb, 0x30,
0x42, 0xfa, 0x1a, 0x14, 0x75, 0x73, 0xdb, 0xf2, 0x64, 0xb4, 0x30, 0xc6, 0x28, 0xc9, 0x5a, 0x0c,
0x59, 0x36, 0xe0, 0xe4, 0x0a, 0x76, 0x3b, 0xa6, 0x83, 0x6d, 0x77, 0x49, 0x37, 0x07, 0x56, 0x7f,
0x5d, 0x75, 0x77, 0x0e, 0x61, 0x50, 0x21, 0xdb, 0xc8, 0x45, 0x6c, 0x43, 0xfe, 0x8d, 0x04, 0xa7,
0x92, 0xd7, 0xe3, 0x5b, 0x6f, 0x43, 0x79, 0x5b, 0xc7, 0x03, 0x8d, 0xc8, 0x57, 0xa2, 0xf2, 0x15,
0x63, 0x62, 0x58, 0x43, 0x82, 0xcc, 0x77, 0x78, 0x2e, 0x45, 0x9b, 0x37, 0x5c, 0x5b, 0x37, 0xfb,
0xab, 0xba, 0xe3, 0x2a, 0x0c, 0x3f, 0x20, 0xcf, 0x7c, 0x76, 0x35, 0xfe, 0x81, 0x04, 0x0b, 0x2b,
0xd8, 0xbd, 0x29, 0xfc, 0x32, 0xf9, 0xae, 0x3b, 0xae, 0xde, 0x73, 0x9e, 0x6c, 0x46, 0x93, 0x21,
0x40, 0xcb, 0x9f, 0x49, 0x70, 0x26, 0x95, 0x19, 0x2e, 0x3a, 0xee, 0x77, 0x3c, 0xaf, 0x9c, 0xec,
0x77, 0xbe, 0x81, 0xf7, 0xdf, 0x53, 0x07, 0x23, 0xbc, 0xae, 0xea, 0x36, 0xf3, 0x3b, 0x53, 0x7a,
0xe1, 0xdf, 0x4b, 0x70, 0x7a, 0x05, 0xbb, 0xeb, 0x5e, 0x4c, 0x7a, 0x86, 0xd2, 0x99, 0x9c, 0xbe,
0xc8, 0x3f, 0x62, 0x87, 0x99, 0xc8, 0xed, 0x33, 0x11, 0xdf, 0x02, 0xb5, 0x83, 0x80, 0x41, 0xde,
0x64, 0x89, 0x03, 0x17, 0x9e, 0xfc, 0x4b, 0x09, 0x4e, 0xdc, 0xe8, 0x3d, 0x1c, 0xe9, 0x36, 0xe6,
0x48, 0xab, 0x56, 0x6f, 0x77, 0x7a, 0xd1, 0xfa, 0x49, 0x56, 0x2e, 0x94, 0x64, 0x4d, 0x4a, 0xa7,
0xe7, 0xa1, 0xe4, 0xb2, 0xac, 0x8e, 0x49, 0x95, 0x8f, 0x28, 0x7f, 0x0a, 0x1e, 0x60, 0xd5, 0xf9,
0xff, 0xe4, 0xef, 0xb3, 0x02, 0xd4, 0xde, 0xe3, 0xc9, 0x18, 0x8d, 0xd9, 0x51, 0x3d, 0x92, 0x92,
0xf5, 0x28, 0x90, 0xbf, 0x25, 0xa5, 0x74, 0x2b, 0x50, 0x77, 0x30, 0xde, 0x9d, 0x26, 0x42, 0xd7,
0xc8, 0x44, 0x11, 0x59, 0x57, 0x61, 0x6e, 0x64, 0x6e, 0x93, 0x1a, 0x04, 0x6b, 0x5c, 0x80, 0xac,
0x14, 0x98, 0xec, 0xb9, 0xe3, 0x13, 0xd1, 0x1d, 0x98, 0x8d, 0xd2, 0x2a, 0x66, 0xa2, 0x15, 0x9d,
0x86, 0x3a, 0xd0, 0xd4, 0x6c, 0x6b, 0x38, 0xc4, 0x5a, 0xd7, 0xf1, 0x48, 0x95, 0xb2, 0x91, 0xe2,
0xf3, 0x04, 0xa9, 0x57, 0xe0, 0x68, 0x94, 0xd3, 0x8e, 0x46, 0xd2, 0x51, 0x72, 0x86, 0x49, 0x9f,
0xd0, 0x15, 0x98, 0x8b, 0xe3, 0x97, 0x29, 0x7e, 0xfc, 0x03, 0x7a, 0x19, 0x50, 0x84, 0x55, 0x82,
0x5e, 0x61, 0xe8, 0x61, 0x66, 0x3a, 0x9a, 0x23, 0x7f, 0x2a, 0xc1, 0xfc, 0x03, 0xd5, 0xed, 0xed,
0x2c, 0x1b, 0xdc, 0xd6, 0x0e, 0xe1, 0xa9, 0xde, 0x86, 0xca, 0x23, 0xae, 0x17, 0x5e, 0x38, 0x3a,
0x93, 0x20, 0x9f, 0xa0, 0x06, 0x2a, 0xfe, 0x0c, 0xf9, 0x4b, 0x09, 0x8e, 0xd1, 0x02, 0xd4, 0x13,
0xd6, 0x57, 0xef, 0x33, 0x27, 0x14, 0xa1, 0xe8, 0x22, 0x34, 0x0c, 0xd5, 0xde, 0xdd, 0xf0, 0x71,
0x8a, 0x14, 0x27, 0x02, 0x95, 0x1f, 0x03, 0xf0, 0xd1, 0x9a, 0xd3, 0x9f, 0x82, 0xff, 0x37, 0x60,
0x86, 0xaf, 0xca, 0xdd, 0xe7, 0x24, 0x3d, 0xf3, 0xd0, 0xe5, 0xbf, 0x4a, 0xd0, 0xf0, 0x03, 0x22,
0x35, 0xf2, 0x06, 0xe4, 0x84, 0x69, 0xe7, 0x3a, 0xcb, 0xe8, 0x6d, 0x28, 0xb1, 0xe6, 0x04, 0xa7,
0x7d, 0x21, 0x4c, 0x9b, 0x37, 0x2e, 0x02, 0x51, 0x95, 0x02, 0x14, 0x3e, 0x89, 0xc8, 0x48, 0x04,
0x11, 0xe1, 0x7c, 0x7c, 0x08, 0xea, 0xc0, 0x6c, 0x38, 0x61, 0xf7, 0x4c, 0xf8, 0x6c, 0x5a, 0xf0,
0x58, 0x56, 0x5d, 0x95, 0xc6, 0x8e, 0x46, 0x28, 0x5f, 0x77, 0xe4, 0xff, 0x16, 0xa1, 0x1a, 0xd8,
0x65, 0x6c, 0x27, 0xd1, 0x23, 0xcd, 0x4d, 0x0e, 0x83, 0xf9, 0x78, 0xd5, 0x78, 0x01, 0x1a, 0x3a,
0x4d, 0xbd, 0xba, 0x5c, 0x15, 0xa9, 0xd7, 0xac, 0x28, 0x75, 0x06, 0xe5, 0x76, 0x81, 0x16, 0xa0,
0x6a, 0x8e, 0x8c, 0xae, 0xb5, 0xdd, 0xb5, 0xad, 0x3d, 0x87, 0x97, 0x9f, 0x15, 0x73, 0x64, 0x7c,
0x73, 0x5b, 0xb1, 0xf6, 0x1c, 0xbf, 0xc2, 0x29, 0x1d, 0xb0, 0xc2, 0x59, 0x80, 0xaa, 0xa1, 0x3e,
0x26, 0x54, 0xbb, 0xe6, 0xc8, 0xa0, 0x95, 0x69, 0x5e, 0xa9, 0x18, 0xea, 0x63, 0xc5, 0xda, 0xbb,
0x3b, 0x32, 0xd0, 0x25, 0x68, 0x0e, 0x54, 0xc7, 0xed, 0x06, 0x4b, 0xdb, 0x32, 0x2d, 0x6d, 0x1b,
0x04, 0x7e, 0xcb, 0x2f, 0x6f, 0xe3, 0xb5, 0x52, 0xe5, 0x10, 0xb5, 0x92, 0x66, 0x0c, 0x7c, 0x42,
0x90, 0xbd, 0x56, 0xd2, 0x8c, 0x81, 0x20, 0xf3, 0x06, 0xcc, 0x6c, 0xd1, 0x84, 0xd6, 0x69, 0x55,
0x53, 0x1d, 0xe6, 0x6d, 0x92, 0xcb, 0xb2, 0xbc, 0x57, 0xf1, 0xd0, 0xd1, 0x5b, 0x50, 0xa1, 0x99,
0x04, 0x9d, 0x5b, 0xcb, 0x34, 0xd7, 0x9f, 0x40, 0x66, 0x6b, 0x78, 0xe0, 0xaa, 0x74, 0x76, 0x3d,
0xdb, 0x6c, 0x31, 0x81, 0x38, 0xe9, 0x9e, 0x8d, 0x55, 0x17, 0x6b, 0x4b, 0xfb, 0x37, 0x2d, 0x63,
0xa8, 0x52, 0x65, 0x6a, 0x35, 0x68, 0xd1, 0x92, 0xf4, 0x89, 0x38, 0x86, 0x9e, 0x18, 0xdd, 0xb6,
0x2d, 0xa3, 0x35, 0xcb, 0x1c, 0x43, 0x18, 0x8a, 0x4e, 0x03, 0x78, 0xee, 0x59, 0x75, 0x5b, 0x4d,
0x7a, 0x8a, 0x15, 0x0e, 0xb9, 0xe1, 0xca, 0x1f, 0xc1, 0x31, 0x5f, 0x43, 0x02, 0xa7, 0x11, 0x3f,
0x58, 0x69, 0xda, 0x83, 0x1d, 0x5f, 0x8a, 0xfc, 0xbd, 0x00, 0xf3, 0x1b, 0xea, 0x23, 0xfc, 0xf4,
0xab, 0x9e, 0x4c, 0xfe, 0x78, 0x15, 0xe6, 0x68, 0xa1, 0xb3, 0x18, 0xe0, 0x67, 0x4c, 0x42, 0x10,
0x3c, 0xce, 0xf8, 0x44, 0xf4, 0x2e, 0xc9, 0x64, 0x70, 0x6f, 0x77, 0xdd, 0xd2, 0xfd, 0x64, 0xe0,
0x74, 0x02, 0x9d, 0x9b, 0x02, 0x4b, 0x09, 0xce, 0x40, 0xeb, 0x71, 0xd7, 0xc6, 0xd2, 0x80, 0x17,
0xc6, 0xd6, 0xde, 0xbe, 0xf4, 0xa3, 0x1e, 0x0e, 0xb5, 0x60, 0x86, 0xc7, 0x70, 0x6a, 0xf7, 0x65,
0xc5, 0x1b, 0xa2, 0x75, 0x38, 0xca, 0x76, 0xb0, 0xc1, 0x95, 0x9a, 0x6d, 0xbe, 0x9c, 0x69, 0xf3,
0x49, 0x53, 0xc3, 0x36, 0x51, 0x39, 0xa8, 0x4d, 0xb4, 0x60, 0x86, 0xeb, 0x29, 0xf5, 0x05, 0x65,
0xc5, 0x1b, 0x92, 0x63, 0x66, 0x5d, 0x4d, 0xdd, 0xec, 0xb7, 0xaa, 0xf4, 0x9b, 0x0f, 0x20, 0x15,
0x23, 0xf8, 0xf2, 0x9c, 0xd0, 0x25, 0x7a, 0x07, 0xca, 0x42, 0xc3, 0x73, 0x99, 0x35, 0x5c, 0xcc,
0x89, 0xfa, 0xe8, 0x7c, 0xc4, 0x47, 0xcb, 0x7f, 0x93, 0xa0, 0xb6, 0x4c, 0xb6, 0xb4, 0x6a, 0xf5,
0x69, 0x44, 0xb9, 0x00, 0x0d, 0x1b, 0xf7, 0x2c, 0x5b, 0xeb, 0x62, 0xd3, 0xb5, 0x75, 0xcc, 0x9a,
0x0b, 0x05, 0xa5, 0xce, 0xa0, 0xb7, 0x18, 0x90, 0xa0, 0x11, 0xb7, 0xeb, 0xb8, 0xaa, 0x31, 0xec,
0x6e, 0x13, 0xf3, 0xce, 0x31, 0x34, 0x01, 0xa5, 0xd6, 0x7d, 0x0e, 0x6a, 0x3e, 0x9a, 0x6b, 0xd1,
0xf5, 0x0b, 0x4a, 0x55, 0xc0, 0x36, 0x2d, 0xf4, 0x3c, 0x34, 0xa8, 0x4c, 0xbb, 0x03, 0xab, 0xdf,
0x25, 0x85, 0x38, 0x0f, 0x36, 0x35, 0x8d, 0xb3, 0x45, 0xce, 0x2a, 0x8c, 0xe5, 0xe8, 0x1f, 0x62,
0x1e, 0x6e, 0x04, 0xd6, 0x86, 0xfe, 0x21, 0x26, 0xb1, 0xbe, 0x4e, 0x62, 0xe7, 0x5d, 0x4b, 0xc3,
0x9b, 0x53, 0x66, 0x1a, 0x19, 0x3a, 0xb6, 0xa7, 0xa0, 0x22, 0x76, 0xc0, 0xb7, 0xe4, 0x03, 0xd0,
0x6d, 0x68, 0x78, 0x39, 0x71, 0x97, 0x95, 0x8a, 0x85, 0xd4, 0xcc, 0x2f, 0x10, 0xfd, 0x1c, 0xa5,
0xee, 0x4d, 0xa3, 0x43, 0xf9, 0x36, 0xd4, 0x82, 0x9f, 0xc9, 0xaa, 0x1b, 0x51, 0x45, 0x11, 0x00,
0xa2, 0x8d, 0x77, 0x47, 0x06, 0x39, 0x53, 0xee, 0x58, 0xbc, 0xa1, 0xfc, 0x89, 0x04, 0x75, 0x1e,
0xb2, 0x37, 0xc4, 0x8d, 0x04, 0xdd, 0x9a, 0x44, 0xb7, 0x46, 0x7f, 0xa3, 0xaf, 0x87, 0xdb, 0x91,
0xcf, 0x27, 0x3a, 0x01, 0x4a, 0x84, 0x66, 0xc7, 0xa1, 0x78, 0x9d, 0xa5, 0x35, 0xf1, 0x31, 0x51,
0x34, 0x7e, 0x34, 0x54, 0xd1, 0x5a, 0x30, 0xa3, 0x6a, 0x9a, 0x8d, 0x1d, 0x87, 0xf3, 0xe1, 0x0d,
0xc9, 0x97, 0x47, 0xd8, 0x76, 0x3c, 0x95, 0xcf, 0x2b, 0xde, 0x10, 0xbd, 0x05, 0x65, 0x91, 0x4e,
0xe7, 0x93, 0x52, 0xa8, 0x20, 0x9f, 0xbc, 0x94, 0x16, 0x33, 0xe4, 0x3f, 0xe6, 0xa0, 0xc1, 0x05,
0xb6, 0xc4, 0x63, 0xea, 0x78, 0xe3, 0x5b, 0x82, 0xda, 0xb6, 0x6f, 0xfb, 0xe3, 0x5a, 0x66, 0x41,
0x17, 0x11, 0x9a, 0x33, 0xc9, 0x00, 0xc3, 0x51, 0xbd, 0x70, 0xa8, 0xa8, 0x5e, 0x3c, 0xa8, 0x07,
0x8b, 0xe7, 0x79, 0xa5, 0x84, 0x3c, 0x4f, 0xfe, 0x0e, 0x54, 0x03, 0x04, 0xa8, 0x87, 0x66, 0xbd,
0x36, 0x2e, 0x31, 0x6f, 0x88, 0xae, 0xfb, 0xb9, 0x0d, 0x13, 0xd5, 0x89, 0x04, 0x5e, 0x22, 0x69,
0x8d, 0xfc, 0x5b, 0x09, 0x4a, 0x9c, 0xf2, 0x19, 0xa8, 0x72, 0xa7, 0x43, 0xf3, 0x3e, 0x46, 0x1d,
0x38, 0x88, 0x24, 0x7e, 0x4f, 0xce, 0xeb, 0x9c, 0x80, 0x72, 0xc4, 0xdf, 0xcc, 0xf0, 0xb0, 0xe0,
0x7d, 0x0a, 0x38, 0x19, 0xf2, 0x89, 0xfa, 0x97, 0x2f, 0x25, 0x7a, 0xa9, 0xa0, 0xe0, 0x9e, 0xf5,
0x08, 0xdb, 0xfb, 0x87, 0xef, 0xc6, 0xbe, 0x19, 0x50, 0xe8, 0x8c, 0xf5, 0xa1, 0x98, 0x80, 0xde,
0xf4, 0xc5, 0x9d, 0x4f, 0x6a, 0x46, 0x05, 0x3d, 0x0c, 0x57, 0x47, 0x5f, 0xec, 0x3f, 0x66, 0x7d,
0xe5, 0xf0, 0x56, 0xa6, 0xcd, 0x6b, 0x9e, 0x48, 0xd9, 0x21, 0xff, 0x44, 0x82, 0x13, 0x2b, 0xd8,
0xbd, 0x1d, 0xee, 0x35, 0x3c, 0x6b, 0xae, 0x0c, 0x68, 0x27, 0x31, 0x75, 0x98, 0x53, 0x6f, 0x43,
0x59, 0x74, 0x4d, 0xd8, 0xed, 0x80, 0x18, 0xcb, 0xdf, 0x97, 0xa0, 0xc5, 0x57, 0xa1, 0x6b, 0x92,
0x94, 0x7a, 0x80, 0x5d, 0xac, 0x7d, 0xd5, 0x75, 0xf3, 0x17, 0x12, 0x34, 0x83, 0x1e, 0x9f, 0x3a,
0xed, 0xd7, 0xa0, 0x48, 0xdb, 0x13, 0x9c, 0x83, 0x89, 0xca, 0xca, 0xb0, 0x89, 0xcb, 0xa0, 0x69,
0xde, 0xa6, 0x08, 0x4e, 0x7c, 0xe8, 0x87, 0x9d, 0xfc, 0xc1, 0xc3, 0x0e, 0x0f, 0xc3, 0xd6, 0x88,
0xd0, 0x65, 0x7d, 0x3d, 0x1f, 0x20, 0x7f, 0x9e, 0x83, 0x96, 0x5f, 0x8f, 0x7c, 0xe5, 0x7e, 0x3f,
0x25, 0x5b, 0xcd, 0x3f, 0xa1, 0x6c, 0xb5, 0x70, 0x78, 0x5f, 0x5f, 0x4c, 0xf2, 0xf5, 0x7f, 0xc9,
0x41, 0xc3, 0x97, 0xda, 0xfa, 0x40, 0x35, 0xd1, 0x3c, 0x94, 0x86, 0x03, 0xd5, 0x6f, 0x86, 0xf2,
0x11, 0xda, 0x10, 0x79, 0x4e, 0x58, 0x4e, 0x2f, 0x25, 0x9d, 0x61, 0xca, 0x41, 0x28, 0x11, 0x12,
0xa4, 0x1c, 0x64, 0x05, 0x05, 0x2d, 0xea, 0x79, 0x6e, 0xc5, 0x94, 0x85, 0xd4, 0xf3, 0x57, 0x00,
0xf1, 0x13, 0xee, 0xea, 0x66, 0xd7, 0xc1, 0x3d, 0xcb, 0xd4, 0xd8, 0xd9, 0x17, 0x95, 0x26, 0xff,
0xd2, 0x31, 0x37, 0x18, 0x1c, 0xbd, 0x06, 0x05, 0x77, 0x7f, 0xc8, 0xbc, 0x78, 0x23, 0xd1, 0x3b,
0xfa, 0x7c, 0x6d, 0xee, 0x0f, 0xb1, 0x42, 0xd1, 0xd1, 0x02, 0x00, 0x21, 0xe5, 0xda, 0xea, 0x23,
0x1e, 0x12, 0x0b, 0x4a, 0x00, 0x42, 0xb4, 0xd9, 0x93, 0xe1, 0x0c, 0x0b, 0x1d, 0x7c, 0x28, 0xff,
0x29, 0x07, 0x4d, 0x9f, 0xa4, 0x82, 0x9d, 0xd1, 0xc0, 0x4d, 0x95, 0xdf, 0xf8, 0x62, 0x70, 0x52,
0xde, 0xf0, 0x2e, 0x54, 0xf9, 0x79, 0x1e, 0x40, 0x1f, 0x80, 0x4d, 0x59, 0x1d, 0xa3, 0xa0, 0xc5,
0x27, 0xa4, 0xa0, 0xa5, 0x03, 0x2a, 0xa8, 0xbc, 0x01, 0xf3, 0x9e, 0xdf, 0xf3, 0x11, 0xd6, 0xb0,
0xab, 0x8e, 0x49, 0x38, 0xce, 0x40, 0x95, 0xc5, 0x33, 0x16, 0xc8, 0x59, 0xaa, 0x0e, 0x5b, 0xa2,
0xc2, 0x95, 0xbf, 0x0b, 0xc7, 0xa8, 0xdf, 0x88, 0xb6, 0x72, 0xb3, 0xb4, 0xf9, 0x65, 0x51, 0x08,
0x90, 0xa4, 0x9f, 0x69, 0x77, 0x45, 0x09, 0xc1, 0xe4, 0x55, 0x78, 0x2e, 0x42, 0xff, 0x10, 0x71,
0x81, 0xa4, 0x42, 0xf3, 0x1b, 0xe1, 0x2b, 0xf1, 0xe9, 0xa3, 0xdf, 0x69, 0xd1, 0xb9, 0xed, 0xea,
0x5a, 0x54, 0xbf, 0x34, 0xf4, 0x0e, 0x54, 0x4c, 0xbc, 0xd7, 0x0d, 0x3a, 0xdf, 0x0c, 0x0d, 0xba,
0xb2, 0x89, 0xf7, 0xe8, 0x2f, 0xf9, 0x2e, 0x1c, 0x8f, 0xb1, 0x7a, 0x98, 0xbd, 0xff, 0x59, 0x82,
0x13, 0xcb, 0xb6, 0x35, 0x7c, 0x4f, 0xb7, 0xdd, 0x91, 0x3a, 0x08, 0xdf, 0x73, 0x3d, 0x9d, 0x32,
0xee, 0x4e, 0x20, 0x0c, 0x33, 0xbf, 0x7c, 0x25, 0x41, 0x5d, 0xe3, 0x4c, 0xf1, 0x4d, 0x07, 0x82,
0xf6, 0xbf, 0xf2, 0x49, 0xcc, 0x73, 0xbc, 0x09, 0xc1, 0x26, 0x4b, 0x96, 0x92, 0xd8, 0xf5, 0xc9,
0x4f, 0xdb, 0xf5, 0x49, 0xb1, 0xfc, 0xc2, 0x13, 0xb2, 0xfc, 0x03, 0x97, 0x21, 0x77, 0x20, 0xdc,
0x91, 0xa3, 0x2e, 0x77, 0xaa, 0x56, 0xde, 0x12, 0x80, 0xdf, 0x9d, 0xe2, 0x2f, 0x9a, 0xb2, 0x90,
0x09, 0xcc, 0x22, 0xa7, 0x25, 0xbc, 0x2c, 0xed, 0x2a, 0x87, 0xfa, 0x25, 0xf7, 0xa0, 0x9d, 0xa4,
0xa5, 0x87, 0xd1, 0xfc, 0xcf, 0x73, 0x00, 0x1d, 0xf1, 0x08, 0x6e, 0xba, 0x8c, 0xf2, 0x3c, 0xd4,
0x7d, 0x85, 0xf1, 0xed, 0x3d, 0xa8, 0x45, 0x1a, 0x31, 0x09, 0x91, 0xd8, 0x12, 0x9c, 0x58, 0xb2,
0xab, 0x51, 0x3a, 0x01, 0xab, 0x61, 0x4a, 0x11, 0x71, 0x7a, 0xe8, 0x24, 0x54, 0x6c, 0x6b, 0xaf,
0x4b, 0xcc, 0x4c, 0xf3, 0x5e, 0xf9, 0xd9, 0xd6, 0x1e, 0x31, 0x3e, 0x0d, 0x1d, 0x87, 0x19, 0x57,
0x75, 0x76, 0x09, 0xfd, 0x52, 0xe0, 0xaa, 0x55, 0x43, 0xc7, 0xa0, 0xb8, 0xad, 0x0f, 0x30, 0xbb,
0xd9, 0xab, 0x28, 0x6c, 0x80, 0x5e, 0xf7, 0x9e, 0xa3, 0x94, 0x33, 0x5f, 0xa7, 0xb3, 0x17, 0x29,
0x5f, 0x4a, 0x30, 0xeb, 0x4b, 0x8d, 0x3a, 0x20, 0xe2, 0xd3, 0xa8, 0x3f, 0xbb, 0x69, 0x69, 0xcc,
0x55, 0x34, 0x52, 0xae, 0x58, 0xd8, 0x44, 0xe6, 0xb5, 0xfc, 0x29, 0xe3, 0xf2, 0x72, 0xb2, 0x2f,
0xb2, 0x69, 0x5d, 0xf3, 0x6e, 0x78, 0x4a, 0xb6, 0xb5, 0xd7, 0xd1, 0x84, 0x34, 0xd8, 0x13, 0x3e,
0x96, 0x85, 0x12, 0x69, 0xdc, 0xa4, 0xaf, 0xf8, 0xce, 0x43, 0x1d, 0xdb, 0xb6, 0x65, 0x77, 0x0d,
0xec, 0x38, 0x6a, 0x1f, 0xf3, 0xa4, 0xab, 0x46, 0x81, 0x6b, 0x0c, 0x26, 0x7f, 0x91, 0x87, 0x86,
0xbf, 0x15, 0xef, 0x5e, 0x47, 0xd7, 0xbc, 0x7b, 0x1d, 0x9d, 0x1c, 0x1d, 0xd8, 0xcc, 0x15, 0x8a,
0xc3, 0x5d, 0xca, 0xb5, 0x24, 0xa5, 0xc2, 0xa1, 0x1d, 0x8d, 0xc4, 0x42, 0x62, 0x64, 0xa6, 0xa5,
0x61, 0xff, 0x70, 0xc1, 0x03, 0xf1, 0xb3, 0x0d, 0xe9, 0x48, 0x21, 0x83, 0x8e, 0x14, 0x33, 0xe8,
0x48, 0x29, 0x41, 0x47, 0xe6, 0xa1, 0xb4, 0x35, 0xea, 0xed, 0x62, 0x97, 0xa7, 0x48, 0x7c, 0x14,
0xd6, 0x9d, 0x72, 0x44, 0x77, 0x84, 0x8a, 0x54, 0x82, 0x2a, 0x72, 0x12, 0x2a, 0xec, 0x82, 0xa1,
0xeb, 0x3a, 0xb4, 0xd3, 0x9a, 0x57, 0xca, 0x0c, 0xb0, 0xe9, 0xa0, 0x37, 0xbc, 0xfa, 0xa1, 0x9a,
0x64, 0xec, 0xd4, 0xeb, 0x44, 0xb4, 0xc4, 0xab, 0x1e, 0x2e, 0x40, 0x83, 0x3e, 0x71, 0x7e, 0x38,
0xc2, 0xf6, 0xbe, 0xba, 0x35, 0xc0, 0xad, 0x1a, 0x65, 0xa7, 0x4e, 0xa0, 0xf7, 0x3c, 0x20, 0x11,
0x08, 0x45, 0xd3, 0x4d, 0x0d, 0x3f, 0xc6, 0x5a, 0xab, 0x4e, 0x91, 0xa8, 0xa8, 0x3b, 0x0c, 0x24,
0x7f, 0x00, 0xc8, 0x5f, 0xe3, 0x70, 0x95, 0x61, 0xe4, 0x10, 0x73, 0xd1, 0x43, 0x94, 0x7f, 0x27,
0xc1, 0x5c, 0x70, 0xb1, 0x69, 0xc3, 0xe3, 0x3b, 0x50, 0x65, 0x1d, 0xe9, 0x2e, 0x31, 0x4f, 0x5e,
0x1b, 0x9e, 0x1e, 0x2b, 0x3d, 0x05, 0xfc, 0xa7, 0xba, 0x44, 0x09, 0xf6, 0x2c, 0x7b, 0x57, 0x37,
0xfb, 0x5d, 0xc2, 0x99, 0x67, 0x14, 0x35, 0x0e, 0xbc, 0x4b, 0x60, 0xf2, 0xa7, 0x12, 0x2c, 0xdc,
0x1f, 0x6a, 0xaa, 0x8b, 0x03, 0x79, 0xc2, 0x61, 0x5f, 0xff, 0xbc, 0xe6, 0x3d, 0xc0, 0xc9, 0x65,
0xeb, 0xaa, 0x32, 0x6c, 0x79, 0x0d, 0x4e, 0x28, 0xd8, 0xc1, 0xa6, 0x16, 0xfa, 0x38, 0x2d, 0x17,
0xf2, 0x10, 0xda, 0x49, 0xe4, 0x0e, 0x73, 0xf6, 0x2c, 0x61, 0xeb, 0xda, 0x84, 0xac, 0xcb, 0xfd,
0x0f, 0xc9, 0x13, 0xe8, 0x3a, 0xae, 0xfc, 0x6f, 0x09, 0xe6, 0x6e, 0x68, 0xde, 0x7a, 0x4f, 0x2d,
0x2f, 0x8c, 0xe6, 0x4d, 0xf9, 0x78, 0xde, 0xf4, 0xa4, 0x1c, 0x09, 0x77, 0xa9, 0xe6, 0xc8, 0xf0,
0x42, 0x85, 0x4d, 0xef, 0x77, 0xe5, 0x6d, 0x71, 0xe9, 0xa7, 0xe0, 0x6d, 0x6c, 0x63, 0xb3, 0x87,
0x57, 0xad, 0xde, 0x6e, 0xe0, 0x15, 0x8f, 0x14, 0x7c, 0xc5, 0x33, 0xed, 0xab, 0xa0, 0xcb, 0x3f,
0x97, 0x60, 0x2e, 0xd6, 0x5d, 0x40, 0x0d, 0x80, 0xfb, 0x66, 0x8f, 0xb7, 0x5d, 0x9a, 0x47, 0x50,
0x0d, 0xca, 0x5e, 0x13, 0xa6, 0x29, 0xa1, 0x2a, 0xcc, 0x6c, 0x5a, 0x14, 0xbb, 0x99, 0x43, 0x4d,
0xa8, 0xb1, 0x89, 0xa3, 0x5e, 0x0f, 0x3b, 0x4e, 0x33, 0x2f, 0x20, 0xb7, 0x55, 0x7d, 0x30, 0xb2,
0x71, 0xb3, 0x80, 0xea, 0x50, 0xd9, 0xb4, 0xf8, 0x1b, 0xa8, 0x66, 0x11, 0x21, 0x68, 0x78, 0x0f,
0xa2, 0xf8, 0xa4, 0x52, 0x00, 0xe6, 0x4d, 0x9b, 0xb9, 0xbc, 0x1d, 0xac, 0xc3, 0x49, 0x71, 0x8a,
0x8e, 0xc3, 0xd1, 0xfb, 0xa6, 0x86, 0xb7, 0x75, 0x13, 0x6b, 0xfe, 0xa7, 0xe6, 0x11, 0x74, 0x14,
0x66, 0x3b, 0xa6, 0x89, 0xed, 0x00, 0x50, 0x22, 0xc0, 0x35, 0x6c, 0xf7, 0x71, 0x00, 0x98, 0x43,
0x73, 0x50, 0x5f, 0xd3, 0x1f, 0x07, 0x40, 0xf9, 0xc5, 0x7f, 0x1e, 0x87, 0xca, 0xb2, 0xea, 0xaa,
0x37, 0x2d, 0xcb, 0xd6, 0xd0, 0x10, 0x10, 0x7d, 0x3f, 0x68, 0x0c, 0x2d, 0x53, 0xbc, 0xca, 0x45,
0xaf, 0xa4, 0xa4, 0x50, 0x71, 0x54, 0xae, 0x96, 0xed, 0x8b, 0x29, 0x33, 0x22, 0xe8, 0xf2, 0x11,
0x64, 0xd0, 0x15, 0x49, 0x71, 0xbf, 0xa9, 0xf7, 0x76, 0xbd, 0xa7, 0x05, 0x63, 0x56, 0x8c, 0xa0,
0x7a, 0x2b, 0x46, 0x1e, 0xfb, 0xf2, 0x01, 0x7b, 0xe4, 0xe9, 0xd9, 0xa5, 0x7c, 0x04, 0x3d, 0x84,
0x63, 0x2b, 0x38, 0xe0, 0x87, 0xbc, 0x05, 0x17, 0xd3, 0x17, 0x8c, 0x21, 0x1f, 0x70, 0xc9, 0x55,
0x28, 0xd2, 0x4e, 0x1e, 0x4a, 0x72, 0x55, 0xc1, 0xbf, 0xbe, 0xb4, 0xcf, 0xa6, 0x23, 0x08, 0x6a,
0x1f, 0xc0, 0x6c, 0xe4, 0xe9, 0x3d, 0x7a, 0x31, 0x61, 0x5a, 0xf2, 0x9f, 0x28, 0xda, 0x97, 0xb3,
0xa0, 0x8a, 0xb5, 0xfa, 0xd0, 0x08, 0xbf, 0x3e, 0x44, 0x97, 0x12, 0xe6, 0x27, 0xbe, 0x9a, 0x6e,
0xbf, 0x98, 0x01, 0x53, 0x2c, 0x64, 0x40, 0x33, 0xfa, 0x14, 0x1c, 0x5d, 0x1e, 0x4b, 0x20, 0xac,
0x6e, 0x2f, 0x65, 0xc2, 0x15, 0xcb, 0xed, 0x53, 0x25, 0x88, 0xbd, 0x2e, 0x46, 0x57, 0x93, 0xc9,
0xa4, 0x3d, 0x7b, 0x6e, 0x5f, 0xcb, 0x8c, 0x2f, 0x96, 0xfe, 0x1e, 0xbb, 0x41, 0x48, 0x7a, 0xa1,
0x8b, 0x5e, 0x4d, 0x26, 0x37, 0xe6, 0x69, 0x71, 0x7b, 0xf1, 0x20, 0x53, 0x04, 0x13, 0x1f, 0xd1,
0xd6, 0x7f, 0xc2, 0x2b, 0xd7, 0xa8, 0xdd, 0x79, 0xf4, 0xd2, 0x9f, 0xef, 0xb6, 0x5f, 0x3d, 0xc0,
0x0c, 0xc1, 0x80, 0x15, 0x7d, 0x6b, 0xef, 0x99, 0xe1, 0xb5, 0x89, 0x5a, 0x33, 0x9d, 0x0d, 0xbe,
0x0f, 0xb3, 0x91, 0x47, 0x1c, 0x89, 0x56, 0x93, 0xfc, 0xd0, 0xa3, 0x3d, 0x2e, 0x7c, 0x33, 0x93,
0x8c, 0xdc, 0xa4, 0xa0, 0x14, 0xed, 0x4f, 0xb8, 0x6d, 0x69, 0x5f, 0xce, 0x82, 0x2a, 0x36, 0xe2,
0x50, 0x77, 0x19, 0xb9, 0x8d, 0x40, 0x57, 0x92, 0x69, 0x24, 0xdf, 0xa4, 0xb4, 0x5f, 0xce, 0x88,
0x2d, 0x16, 0xed, 0x02, 0xac, 0x60, 0x77, 0x0d, 0xbb, 0x36, 0xd1, 0x91, 0x8b, 0x89, 0x22, 0xf7,
0x11, 0xbc, 0x65, 0x5e, 0x98, 0x88, 0x27, 0x16, 0xf8, 0x16, 0x20, 0x2f, 0xc4, 0x06, 0x9e, 0x10,
0x9d, 0x1f, 0xdb, 0xb0, 0x65, 0xdd, 0xd5, 0x49, 0x67, 0xf3, 0x10, 0x9a, 0x6b, 0xaa, 0x49, 0x4a,
0x75, 0x9f, 0xee, 0x95, 0x44, 0xc6, 0xa2, 0x68, 0x29, 0xd2, 0x4a, 0xc5, 0x16, 0x9b, 0xd9, 0x13,
0x31, 0x54, 0x15, 0x26, 0x88, 0xa3, 0xbe, 0xc5, 0x97, 0x46, 0x04, 0x31, 0xc5, 0xb7, 0x8c, 0xc1,
0x17, 0x0b, 0x7f, 0x2c, 0xd1, 0x7f, 0x69, 0x44, 0x10, 0x1e, 0xe8, 0xee, 0xce, 0xfa, 0x40, 0x35,
0x9d, 0x2c, 0x2c, 0x50, 0xc4, 0x03, 0xb0, 0xc0, 0xf1, 0x05, 0x0b, 0x1a, 0xd4, 0x43, 0xfd, 0x50,
0x94, 0xf4, 0x0e, 0x28, 0xa9, 0x23, 0xdb, 0xbe, 0x34, 0x19, 0x51, 0xac, 0xb2, 0x03, 0x75, 0x4f,
0x5f, 0x99, 0x70, 0x5f, 0x4c, 0xe3, 0xd4, 0xc7, 0x49, 0x31, 0xb7, 0x64, 0xd4, 0xa0, 0xb9, 0xc5,
0xdb, 0x3d, 0x28, 0x5b, 0x9b, 0x70, 0x9c, 0xb9, 0xa5, 0xf7, 0x90, 0x98, 0x3f, 0x89, 0xb4, 0x56,
0x93, 0x9d, 0x55, 0x62, 0xa7, 0x38, 0xd1, 0x9f, 0xa4, 0x74, 0x6a, 0xe5, 0x23, 0xe8, 0x01, 0x94,
0xf8, 0xdf, 0x33, 0x9f, 0x1f, 0x5f, 0xfc, 0x71, 0xea, 0x17, 0x26, 0x60, 0x09, 0xc2, 0xbb, 0x70,
0x3c, 0xa5, 0xf4, 0x4b, 0x8c, 0x73, 0xe3, 0xcb, 0xc4, 0x49, 0x56, 0xae, 0x02, 0x8a, 0xff, 0x0b,
0x22, 0xf1, 0x98, 0x52, 0xff, 0x2c, 0x91, 0x61, 0x89, 0xf8, 0x1f, 0x19, 0x12, 0x97, 0x48, 0xfd,
0xbf, 0xc3, 0xa4, 0x25, 0xee, 0x01, 0xf8, 0x05, 0x5e, 0xe2, 0x79, 0xc4, 0xea, 0xbf, 0x09, 0x24,
0x17, 0xff, 0x53, 0x82, 0xb2, 0xf7, 0xea, 0xe6, 0x19, 0x24, 0xf7, 0xcf, 0x20, 0xdb, 0x7e, 0x1f,
0x66, 0x23, 0xcf, 0xf7, 0x13, 0x8d, 0x27, 0xf9, 0x89, 0xff, 0xa4, 0x13, 0x7a, 0xc0, 0xff, 0x10,
0x2e, 0x02, 0xef, 0x0b, 0x69, 0x19, 0x7b, 0x34, 0xe6, 0x4e, 0x20, 0xfc, 0xd4, 0x23, 0xec, 0x5d,
0x80, 0x40, 0x04, 0x1c, 0x7f, 0x15, 0x4a, 0x9c, 0xfa, 0x24, 0x86, 0xd7, 0x0e, 0xe8, 0x37, 0x26,
0x90, 0x73, 0x88, 0x75, 0x45, 0xdb, 0x29, 0x29, 0xd6, 0x95, 0xd2, 0xc4, 0x49, 0xf4, 0xb3, 0xe9,
0x3d, 0x9a, 0xa7, 0x62, 0x6f, 0x4b, 0xd7, 0xbf, 0xfd, 0x6a, 0x5f, 0x77, 0x77, 0x46, 0x5b, 0xe4,
0xcb, 0x35, 0x86, 0xfa, 0xb2, 0x6e, 0xf1, 0x5f, 0xd7, 0x3c, 0x45, 0xbf, 0x46, 0x67, 0x5f, 0x23,
0x6b, 0x0c, 0xb7, 0xb6, 0x4a, 0x74, 0x74, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x9a,
0x38, 0x18, 0x73, 0x41, 0x00, 0x00,
// 3740 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1b, 0x5d, 0x6f, 0x1c, 0x57,
0x35, 0xb3, 0x5f, 0xde, 0x3d, 0xfb, 0xe1, 0xf5, 0x4d, 0xea, 0x6c, 0x36, 0x89, 0x93, 0x4c, 0x9a,
0x34, 0x4d, 0xd3, 0xa4, 0x75, 0xa8, 0x5a, 0xd1, 0x2f, 0xc5, 0x71, 0xe2, 0xac, 0xb0, 0x83, 0x33,
0x76, 0x1a, 0x44, 0x11, 0xab, 0xf1, 0xce, 0xf5, 0x7a, 0xea, 0x9d, 0x99, 0xcd, 0xcc, 0x6c, 0x1c,
0xf7, 0xa5, 0x15, 0x95, 0x90, 0x8a, 0x10, 0x45, 0x42, 0x48, 0x20, 0x81, 0x84, 0x78, 0x02, 0x24,
0x24, 0xa4, 0x8a, 0x07, 0x40, 0x7d, 0xaf, 0xe0, 0x01, 0xf1, 0xcc, 0x0f, 0x80, 0x17, 0xf8, 0x0d,
0xe8, 0x7e, 0xcc, 0x9d, 0xef, 0xdd, 0xf1, 0x3a, 0x69, 0x78, 0xdb, 0x7b, 0xe6, 0xdc, 0x73, 0xcf,
0x3d, 0xf7, 0x7c, 0xdf, 0xbb, 0xd0, 0xd4, 0x54, 0x57, 0xed, 0xf6, 0x2c, 0xcb, 0xd6, 0xae, 0x0e,
0x6d, 0xcb, 0xb5, 0xd0, 0x9c, 0xa1, 0x0f, 0x1e, 0x8d, 0x1c, 0x36, 0xba, 0x4a, 0x3e, 0xb7, 0x6b,
0x3d, 0xcb, 0x30, 0x2c, 0x93, 0x81, 0xda, 0x0d, 0xdd, 0x74, 0xb1, 0x6d, 0xaa, 0x03, 0x3e, 0xae,
0x05, 0x27, 0xb4, 0x6b, 0x4e, 0x6f, 0x07, 0x1b, 0x2a, 0x1b, 0xc9, 0x33, 0x50, 0xbc, 0x65, 0x0c,
0xdd, 0x7d, 0xf9, 0x67, 0x12, 0xd4, 0x6e, 0x0f, 0x46, 0xce, 0x8e, 0x82, 0x1f, 0x8e, 0xb0, 0xe3,
0xa2, 0x57, 0xa0, 0xb0, 0xa5, 0x3a, 0xb8, 0x25, 0x9d, 0x95, 0x2e, 0x55, 0x17, 0x4f, 0x5d, 0x0d,
0xad, 0xca, 0xd7, 0x5b, 0x73, 0xfa, 0x4b, 0xaa, 0x83, 0x15, 0x8a, 0x89, 0x10, 0x14, 0xb4, 0xad,
0xce, 0x72, 0x2b, 0x77, 0x56, 0xba, 0x94, 0x57, 0xe8, 0x6f, 0xb4, 0x00, 0xe0, 0xe0, 0xbe, 0x81,
0x4d, 0xb7, 0xb3, 0xec, 0xb4, 0xf2, 0x67, 0xf3, 0x97, 0xf2, 0x4a, 0x00, 0x82, 0x64, 0xa8, 0xf5,
0xac, 0xc1, 0x00, 0xf7, 0x5c, 0xdd, 0x32, 0x3b, 0xcb, 0xad, 0x02, 0x9d, 0x1b, 0x82, 0xc9, 0xbf,
0x90, 0xa0, 0xce, 0x59, 0x73, 0x86, 0x96, 0xe9, 0x60, 0x74, 0x1d, 0x4a, 0x8e, 0xab, 0xba, 0x23,
0x87, 0x73, 0x77, 0x32, 0x91, 0xbb, 0x0d, 0x8a, 0xa2, 0x70, 0xd4, 0x44, 0xf6, 0xa2, 0xcb, 0xe7,
0xe3, 0xcb, 0x47, 0xb6, 0x50, 0x88, 0x6e, 0x41, 0xfe, 0x87, 0x04, 0xcd, 0x0d, 0x6f, 0xe8, 0x49,
0xef, 0x18, 0x14, 0x7b, 0xd6, 0xc8, 0x74, 0x29, 0x83, 0x75, 0x85, 0x0d, 0xd0, 0x39, 0xa8, 0xf5,
0x76, 0x54, 0xd3, 0xc4, 0x83, 0xae, 0xa9, 0x1a, 0x98, 0xb2, 0x52, 0x51, 0xaa, 0x1c, 0x76, 0x57,
0x35, 0x70, 0x26, 0x8e, 0xce, 0x42, 0x75, 0xa8, 0xda, 0xae, 0x1e, 0x92, 0x59, 0x10, 0x84, 0xda,
0x50, 0xd6, 0x9d, 0x8e, 0x31, 0xb4, 0x6c, 0xb7, 0x55, 0x3c, 0x2b, 0x5d, 0x2a, 0x2b, 0x62, 0x4c,
0x56, 0xd0, 0xe9, 0xaf, 0x4d, 0xd5, 0xd9, 0xed, 0x2c, 0xb7, 0x4a, 0x6c, 0x85, 0x20, 0x4c, 0xfe,
0x95, 0x04, 0xf3, 0x37, 0x1c, 0x47, 0xef, 0x9b, 0xb1, 0x9d, 0xcd, 0x43, 0xc9, 0xb4, 0x34, 0xdc,
0x59, 0xa6, 0x5b, 0xcb, 0x2b, 0x7c, 0x84, 0x4e, 0x42, 0x65, 0x88, 0xb1, 0xdd, 0xb5, 0xad, 0x81,
0xb7, 0xb1, 0x32, 0x01, 0x28, 0xd6, 0x00, 0xa3, 0x7b, 0x30, 0xe7, 0x44, 0x08, 0x31, 0x6d, 0xa8,
0x2e, 0x9e, 0xbf, 0x1a, 0xd3, 0xe7, 0xab, 0xd1, 0x45, 0x95, 0xf8, 0x6c, 0xf9, 0xe3, 0x1c, 0x1c,
0x15, 0x78, 0x8c, 0x57, 0xf2, 0x9b, 0x48, 0xde, 0xc1, 0x7d, 0xc1, 0x1e, 0x1b, 0x64, 0x91, 0xbc,
0x38, 0xb2, 0x7c, 0xf0, 0xc8, 0x32, 0x28, 0x68, 0xf4, 0x3c, 0x8a, 0xf1, 0xf3, 0x38, 0x03, 0x55,
0xfc, 0x78, 0xa8, 0xdb, 0xb8, 0xeb, 0xea, 0x06, 0xa6, 0x22, 0x2f, 0x28, 0xc0, 0x40, 0x9b, 0xba,
0x11, 0xd4, 0xe8, 0x99, 0xcc, 0x1a, 0x2d, 0xff, 0x5a, 0x82, 0xe3, 0xb1, 0x53, 0xe2, 0x26, 0xa2,
0x40, 0x93, 0xee, 0xdc, 0x97, 0x0c, 0x31, 0x16, 0x22, 0xf0, 0x8b, 0xe3, 0x04, 0xee, 0xa3, 0x2b,
0xb1, 0xf9, 0x01, 0x26, 0x73, 0xd9, 0x99, 0xdc, 0x85, 0xe3, 0x2b, 0xd8, 0xe5, 0x0b, 0x90, 0x6f,
0xd8, 0x99, 0xde, 0xc5, 0x84, 0x6d, 0x31, 0x17, 0xb3, 0xc5, 0x3f, 0xe4, 0x84, 0x2d, 0xd2, 0xa5,
0x3a, 0xe6, 0xb6, 0x85, 0x4e, 0x41, 0x45, 0xa0, 0x70, 0xad, 0xf0, 0x01, 0xe8, 0x75, 0x28, 0x12,
0x4e, 0x99, 0x4a, 0x34, 0x16, 0xcf, 0x25, 0xef, 0x29, 0x40, 0x53, 0x61, 0xf8, 0xa8, 0x03, 0x0d,
0xc7, 0x55, 0x6d, 0xb7, 0x3b, 0xb4, 0x1c, 0x7a, 0xce, 0x54, 0x71, 0xaa, 0x8b, 0x72, 0x98, 0x82,
0x70, 0xc6, 0x6b, 0x4e, 0x7f, 0x9d, 0x63, 0x2a, 0x75, 0x3a, 0xd3, 0x1b, 0xa2, 0x5b, 0x50, 0xc3,
0xa6, 0xe6, 0x13, 0x2a, 0x64, 0x26, 0x54, 0xc5, 0xa6, 0x26, 0xc8, 0xf8, 0xe7, 0x53, 0xcc, 0x7e,
0x3e, 0x3f, 0x94, 0xa0, 0x15, 0x3f, 0xa0, 0xc3, 0x38, 0xda, 0x37, 0xd9, 0x24, 0xcc, 0x0e, 0x68,
0xac, 0x85, 0x8b, 0x43, 0x52, 0xf8, 0x14, 0xf9, 0xa7, 0x12, 0x3c, 0xe7, 0xb3, 0x43, 0x3f, 0x3d,
0x2d, 0x6d, 0x41, 0x97, 0xa1, 0xa9, 0x9b, 0xbd, 0xc1, 0x48, 0xc3, 0xf7, 0xcd, 0x3b, 0x58, 0x1d,
0xb8, 0x3b, 0xfb, 0xf4, 0x0c, 0xcb, 0x4a, 0x0c, 0x2e, 0x7f, 0x22, 0xc1, 0x7c, 0x94, 0xaf, 0xc3,
0x08, 0xe9, 0x6b, 0x50, 0xd4, 0xcd, 0x6d, 0xcb, 0x93, 0xd1, 0xc2, 0x18, 0xa3, 0x24, 0x6b, 0x31,
0x64, 0xd9, 0x80, 0x93, 0x2b, 0xd8, 0xed, 0x98, 0x0e, 0xb6, 0xdd, 0x25, 0xdd, 0x1c, 0x58, 0xfd,
0x75, 0xd5, 0xdd, 0x39, 0x84, 0x41, 0x85, 0x6c, 0x23, 0x17, 0xb1, 0x0d, 0xf9, 0x37, 0x12, 0x9c,
0x4a, 0x5e, 0x8f, 0x6f, 0xbd, 0x0d, 0xe5, 0x6d, 0x1d, 0x0f, 0x34, 0x22, 0x5f, 0x89, 0xca, 0x57,
0x8c, 0x89, 0x61, 0x0d, 0x09, 0x32, 0xdf, 0xe1, 0xb9, 0x14, 0x6d, 0xde, 0x70, 0x6d, 0xdd, 0xec,
0xaf, 0xea, 0x8e, 0xab, 0x30, 0xfc, 0x80, 0x3c, 0xf3, 0xd9, 0xd5, 0xf8, 0x07, 0x12, 0x2c, 0xac,
0x60, 0xf7, 0xa6, 0xf0, 0xcb, 0xe4, 0xbb, 0xee, 0xb8, 0x7a, 0xcf, 0x79, 0xb2, 0x19, 0x4d, 0x86,
0x00, 0x2d, 0x7f, 0x26, 0xc1, 0x99, 0x54, 0x66, 0xb8, 0xe8, 0xb8, 0xdf, 0xf1, 0xbc, 0x72, 0xb2,
0xdf, 0xf9, 0x06, 0xde, 0x7f, 0x4f, 0x1d, 0x8c, 0xf0, 0xba, 0xaa, 0xdb, 0xcc, 0xef, 0x4c, 0xe9,
0x85, 0x7f, 0x2f, 0xc1, 0xe9, 0x15, 0xec, 0xae, 0x7b, 0x31, 0xe9, 0x19, 0x4a, 0x87, 0xe0, 0x04,
0x62, 0xa3, 0x97, 0x52, 0x85, 0x60, 0xf2, 0x8f, 0xd8, 0x71, 0x26, 0xf2, 0xfb, 0x4c, 0x04, 0xb8,
0x40, 0x2d, 0x21, 0x60, 0x92, 0x37, 0x59, 0xea, 0xc0, 0xc5, 0x27, 0xff, 0x52, 0x82, 0x13, 0x37,
0x7a, 0x0f, 0x47, 0xba, 0x8d, 0x39, 0xd2, 0xaa, 0xd5, 0xdb, 0x9d, 0x5e, 0xb8, 0x7e, 0x9a, 0x95,
0x0b, 0xa5, 0x59, 0x93, 0x12, 0xea, 0x79, 0x28, 0xb9, 0x2c, 0xaf, 0x63, 0x99, 0x0a, 0x1f, 0x51,
0xfe, 0x14, 0x3c, 0xc0, 0xaa, 0xf3, 0xff, 0xc9, 0xdf, 0x67, 0x05, 0xa8, 0xbd, 0xc7, 0xd3, 0x31,
0x1a, 0xb5, 0xa3, 0x9a, 0x24, 0x25, 0x27, 0x5e, 0x81, 0x0c, 0x2e, 0x29, 0xa9, 0x5b, 0x81, 0xba,
0x83, 0xf1, 0xee, 0x34, 0x31, 0xba, 0x46, 0x26, 0x8a, 0xd8, 0xba, 0x0a, 0x73, 0x23, 0x73, 0x9b,
0x54, 0x21, 0x58, 0xe3, 0x02, 0x64, 0x9a, 0x3b, 0xd9, 0x77, 0xc7, 0x27, 0xa2, 0x3b, 0x30, 0x1b,
0xa5, 0x55, 0xcc, 0x44, 0x2b, 0x3a, 0x0d, 0x75, 0xa0, 0xa9, 0xd9, 0xd6, 0x70, 0x88, 0xb5, 0xae,
0xe3, 0x91, 0x2a, 0x65, 0x23, 0xc5, 0xe7, 0x09, 0x52, 0xaf, 0xc0, 0xd1, 0x28, 0xa7, 0x1d, 0x8d,
0x24, 0xa4, 0xe4, 0x0c, 0x93, 0x3e, 0xa1, 0x2b, 0x30, 0x17, 0xc7, 0x2f, 0x53, 0xfc, 0xf8, 0x07,
0xf4, 0x32, 0xa0, 0x08, 0xab, 0x04, 0xbd, 0xc2, 0xd0, 0xc3, 0xcc, 0x74, 0x34, 0x47, 0xfe, 0x54,
0x82, 0xf9, 0x07, 0xaa, 0xdb, 0xdb, 0x59, 0x36, 0xb8, 0xad, 0x1d, 0xc2, 0x57, 0xbd, 0x0d, 0x95,
0x47, 0x5c, 0x2f, 0xbc, 0x80, 0x74, 0x26, 0x41, 0x3e, 0x41, 0x0d, 0x54, 0xfc, 0x19, 0xf2, 0x97,
0x12, 0x1c, 0xa3, 0x25, 0xa8, 0x27, 0xac, 0xaf, 0xde, 0x6b, 0x4e, 0x28, 0x43, 0xd1, 0x45, 0x68,
0x18, 0xaa, 0xbd, 0xbb, 0xe1, 0xe3, 0x14, 0x29, 0x4e, 0x04, 0x2a, 0x3f, 0x06, 0xe0, 0xa3, 0x35,
0xa7, 0x3f, 0x05, 0xff, 0x6f, 0xc0, 0x0c, 0x5f, 0x95, 0xbb, 0xcf, 0x49, 0x7a, 0xe6, 0xa1, 0xcb,
0x7f, 0x95, 0xa0, 0xe1, 0x87, 0x44, 0x6a, 0xe4, 0x0d, 0xc8, 0x09, 0xd3, 0xce, 0x75, 0x96, 0xd1,
0xdb, 0x50, 0x62, 0xed, 0x09, 0x4e, 0xfb, 0x42, 0x98, 0x36, 0x6f, 0x5d, 0x04, 0xe2, 0x2a, 0x05,
0x28, 0x7c, 0x12, 0x91, 0x91, 0x88, 0x22, 0xc2, 0xf9, 0xf8, 0x10, 0xd4, 0x81, 0xd9, 0x70, 0xca,
0xee, 0x99, 0xf0, 0xd9, 0xb4, 0xe0, 0xb1, 0xac, 0xba, 0x2a, 0x8d, 0x1d, 0x8d, 0x50, 0xc6, 0xee,
0xc8, 0xff, 0x2d, 0x42, 0x35, 0xb0, 0xcb, 0xd8, 0x4e, 0xa2, 0x47, 0x9a, 0x9b, 0x5c, 0x37, 0xe6,
0xe3, 0x75, 0xe3, 0x05, 0x68, 0xe8, 0x34, 0xf9, 0xea, 0x72, 0x55, 0xa4, 0x5e, 0xb3, 0xa2, 0xd4,
0x19, 0x94, 0xdb, 0x05, 0x5a, 0x80, 0xaa, 0x39, 0x32, 0xba, 0xd6, 0x76, 0xd7, 0xb6, 0xf6, 0x1c,
0x5e, 0x80, 0x56, 0xcc, 0x91, 0xf1, 0xcd, 0x6d, 0xc5, 0xda, 0x73, 0xfc, 0x1a, 0xa7, 0x74, 0xc0,
0x1a, 0x67, 0x01, 0xaa, 0x86, 0xfa, 0x98, 0x50, 0xed, 0x9a, 0x23, 0x83, 0xd6, 0xa6, 0x79, 0xa5,
0x62, 0xa8, 0x8f, 0x15, 0x6b, 0xef, 0xee, 0xc8, 0x40, 0x97, 0xa0, 0x39, 0x50, 0x1d, 0xb7, 0x1b,
0x2c, 0x6e, 0xcb, 0xb4, 0xb8, 0x6d, 0x10, 0xf8, 0x2d, 0xbf, 0xc0, 0x8d, 0x57, 0x4b, 0x95, 0x43,
0x54, 0x4b, 0x9a, 0x31, 0xf0, 0x09, 0x41, 0xf6, 0x6a, 0x49, 0x33, 0x06, 0x82, 0xcc, 0x1b, 0x30,
0xb3, 0x45, 0x53, 0x5a, 0xa7, 0x55, 0x4d, 0x75, 0x98, 0xb7, 0x49, 0x36, 0xcb, 0x32, 0x5f, 0xc5,
0x43, 0x47, 0x6f, 0x41, 0x85, 0x66, 0x12, 0x74, 0x6e, 0x2d, 0xd3, 0x5c, 0x7f, 0x02, 0x99, 0xad,
0xe1, 0x81, 0xab, 0xd2, 0xd9, 0xf5, 0x6c, 0xb3, 0xc5, 0x04, 0xe2, 0xa4, 0x7b, 0x36, 0x56, 0x5d,
0xac, 0x2d, 0xed, 0xdf, 0xb4, 0x8c, 0xa1, 0x4a, 0x95, 0xa9, 0xd5, 0xa0, 0x65, 0x4b, 0xd2, 0x27,
0xe2, 0x18, 0x7a, 0x62, 0x74, 0xdb, 0xb6, 0x8c, 0xd6, 0x2c, 0x73, 0x0c, 0x61, 0x28, 0x3a, 0x0d,
0xe0, 0xb9, 0x67, 0xd5, 0x6d, 0x35, 0xe9, 0x29, 0x56, 0x38, 0xe4, 0x86, 0x2b, 0x7f, 0x04, 0xc7,
0x7c, 0x0d, 0x09, 0x9c, 0x46, 0xfc, 0x60, 0xa5, 0x69, 0x0f, 0x76, 0x7c, 0x31, 0xf2, 0xf7, 0x02,
0xcc, 0x6f, 0xa8, 0x8f, 0xf0, 0xd3, 0xaf, 0x7b, 0x32, 0xf9, 0xe3, 0x55, 0x98, 0xa3, 0xa5, 0xce,
0x62, 0x80, 0x9f, 0x31, 0x09, 0x41, 0xf0, 0x38, 0xe3, 0x13, 0xd1, 0xbb, 0x24, 0x93, 0xc1, 0xbd,
0xdd, 0x75, 0x4b, 0xf7, 0x93, 0x81, 0xd3, 0x09, 0x74, 0x6e, 0x0a, 0x2c, 0x25, 0x38, 0x03, 0xad,
0xc7, 0x5d, 0x1b, 0x4b, 0x03, 0x5e, 0x18, 0x5b, 0x7d, 0xfb, 0xd2, 0x8f, 0x7a, 0x38, 0xd4, 0x82,
0x19, 0x1e, 0xc3, 0xa9, 0xdd, 0x97, 0x15, 0x6f, 0x88, 0xd6, 0xe1, 0x28, 0xdb, 0xc1, 0x06, 0x57,
0x6a, 0xb6, 0xf9, 0x72, 0xa6, 0xcd, 0x27, 0x4d, 0x0d, 0xdb, 0x44, 0xe5, 0xa0, 0x36, 0xd1, 0x82,
0x19, 0xae, 0xa7, 0xd4, 0x17, 0x94, 0x15, 0x6f, 0x48, 0x8e, 0x99, 0xf5, 0x35, 0x75, 0xb3, 0xdf,
0xaa, 0xd2, 0x6f, 0x3e, 0x80, 0xd4, 0x8c, 0xe0, 0xcb, 0x73, 0x42, 0x9f, 0xe8, 0x1d, 0x28, 0x0b,
0x0d, 0xcf, 0x65, 0xd6, 0x70, 0x31, 0x27, 0xea, 0xa3, 0xf3, 0x11, 0x1f, 0x2d, 0xff, 0x4d, 0x82,
0xda, 0x32, 0xd9, 0xd2, 0xaa, 0xd5, 0xa7, 0x11, 0xe5, 0x02, 0x34, 0x6c, 0xdc, 0xb3, 0x6c, 0xad,
0x8b, 0x4d, 0xd7, 0xd6, 0x31, 0x6b, 0x2f, 0x14, 0x94, 0x3a, 0x83, 0xde, 0x62, 0x40, 0x82, 0x46,
0xdc, 0xae, 0xe3, 0xaa, 0xc6, 0xb0, 0xbb, 0x4d, 0xcc, 0x3b, 0xc7, 0xd0, 0x04, 0x94, 0x5a, 0xf7,
0x39, 0xa8, 0xf9, 0x68, 0xae, 0x45, 0xd7, 0x2f, 0x28, 0x55, 0x01, 0xdb, 0xb4, 0xd0, 0xf3, 0xd0,
0xa0, 0x32, 0xed, 0x0e, 0xac, 0x7e, 0x97, 0x94, 0xe2, 0x3c, 0xd8, 0xd4, 0x34, 0xce, 0x16, 0x39,
0xab, 0x30, 0x96, 0xa3, 0x7f, 0x88, 0x79, 0xb8, 0x11, 0x58, 0x1b, 0xfa, 0x87, 0x98, 0xc4, 0xfa,
0x3a, 0x89, 0x9d, 0x77, 0x2d, 0x0d, 0x6f, 0x4e, 0x99, 0x69, 0x64, 0xe8, 0xd9, 0x9e, 0x82, 0x8a,
0xd8, 0x01, 0xdf, 0x92, 0x0f, 0x40, 0xb7, 0xa1, 0xe1, 0xe5, 0xc4, 0x5d, 0x56, 0x2a, 0x16, 0x52,
0x33, 0xbf, 0x40, 0xf4, 0x73, 0x94, 0xba, 0x37, 0x8d, 0x0e, 0xe5, 0xdb, 0x50, 0x0b, 0x7e, 0x26,
0xab, 0x6e, 0x44, 0x15, 0x45, 0x00, 0x88, 0x36, 0xde, 0x1d, 0x19, 0xe4, 0x4c, 0xb9, 0x63, 0xf1,
0x86, 0xf2, 0x27, 0x12, 0xd4, 0x79, 0xc8, 0xde, 0x10, 0x77, 0x12, 0x74, 0x6b, 0x12, 0xdd, 0x1a,
0xfd, 0x8d, 0xbe, 0x1e, 0x6e, 0x48, 0x3e, 0x9f, 0xe8, 0x04, 0x28, 0x11, 0x9a, 0x1d, 0x87, 0xe2,
0x75, 0x96, 0xe6, 0xc4, 0xc7, 0x44, 0xd1, 0xf8, 0xd1, 0x50, 0x45, 0x6b, 0xc1, 0x8c, 0xaa, 0x69,
0x36, 0x76, 0x1c, 0xce, 0x87, 0x37, 0x24, 0x5f, 0x1e, 0x61, 0xdb, 0xf1, 0x54, 0x3e, 0xaf, 0x78,
0x43, 0xf4, 0x16, 0x94, 0x45, 0x3a, 0x9d, 0x4f, 0x4a, 0xa1, 0x82, 0x7c, 0xf2, 0x52, 0x5a, 0xcc,
0x90, 0xff, 0x98, 0x83, 0x06, 0x17, 0xd8, 0x12, 0x8f, 0xa9, 0xe3, 0x8d, 0x6f, 0x09, 0x6a, 0xdb,
0xbe, 0xed, 0x8f, 0x6b, 0x9a, 0x05, 0x5d, 0x44, 0x68, 0xce, 0x24, 0x03, 0x0c, 0x47, 0xf5, 0xc2,
0xa1, 0xa2, 0x7a, 0xf1, 0xa0, 0x1e, 0x2c, 0x9e, 0xe7, 0x95, 0x12, 0xf2, 0x3c, 0xf9, 0x3b, 0x50,
0x0d, 0x10, 0xa0, 0x1e, 0x9a, 0x75, 0xdb, 0xb8, 0xc4, 0xbc, 0x21, 0xba, 0xee, 0xe7, 0x36, 0x4c,
0x54, 0x27, 0x12, 0x78, 0x89, 0xa4, 0x35, 0xf2, 0x6f, 0x25, 0x28, 0x71, 0xca, 0x67, 0xa0, 0xca,
0x9d, 0x0e, 0xcd, 0xfb, 0x18, 0x75, 0xe0, 0x20, 0x92, 0xf8, 0x3d, 0x39, 0xaf, 0x73, 0x02, 0xca,
0x11, 0x7f, 0x33, 0xc3, 0xc3, 0x82, 0xf7, 0x29, 0xe0, 0x64, 0xc8, 0x27, 0xea, 0x5f, 0xbe, 0x94,
0xe8, 0xb5, 0x82, 0x82, 0x7b, 0xd6, 0x23, 0x6c, 0xef, 0x1f, 0xbe, 0x1f, 0xfb, 0x66, 0x40, 0xa1,
0x33, 0xd6, 0x87, 0x62, 0x02, 0x7a, 0xd3, 0x17, 0x77, 0x3e, 0xa9, 0x19, 0x15, 0xf4, 0x30, 0x5c,
0x1d, 0x7d, 0xb1, 0xff, 0x98, 0x75, 0x96, 0xc3, 0x5b, 0x99, 0x36, 0xaf, 0x79, 0x22, 0x65, 0x87,
0xfc, 0x13, 0x09, 0x4e, 0xac, 0x60, 0xf7, 0x76, 0xb8, 0xd7, 0xf0, 0xac, 0xb9, 0x32, 0xa0, 0x9d,
0xc4, 0xd4, 0x61, 0x4e, 0xbd, 0x0d, 0x65, 0xd1, 0x35, 0x61, 0xf7, 0x03, 0x62, 0x2c, 0x7f, 0x5f,
0x82, 0x16, 0x5f, 0x85, 0xae, 0x49, 0x52, 0xea, 0x01, 0x76, 0xb1, 0xf6, 0x55, 0xd7, 0xcd, 0x5f,
0x48, 0xd0, 0x0c, 0x7a, 0x7c, 0xea, 0xb4, 0x5f, 0x83, 0x22, 0x6d, 0x4f, 0x70, 0x0e, 0x26, 0x2a,
0x2b, 0xc3, 0x26, 0x2e, 0x83, 0xa6, 0x79, 0x9b, 0x22, 0x38, 0xf1, 0xa1, 0x1f, 0x76, 0xf2, 0x07,
0x0f, 0x3b, 0x3c, 0x0c, 0x5b, 0x23, 0x42, 0x97, 0xf5, 0xf5, 0x7c, 0x80, 0xfc, 0x79, 0x0e, 0x5a,
0x7e, 0x3d, 0xf2, 0x95, 0xfb, 0xfd, 0x94, 0x6c, 0x35, 0xff, 0x84, 0xb2, 0xd5, 0xc2, 0xe1, 0x7d,
0x7d, 0x31, 0xc9, 0xd7, 0xff, 0x25, 0x07, 0x0d, 0x5f, 0x6a, 0xeb, 0x03, 0xd5, 0x44, 0xf3, 0x50,
0x1a, 0x0e, 0x54, 0xbf, 0x19, 0xca, 0x47, 0x68, 0x43, 0xe4, 0x39, 0x61, 0x39, 0xbd, 0x94, 0x74,
0x86, 0x29, 0x07, 0xa1, 0x44, 0x48, 0x90, 0x72, 0x90, 0x15, 0x14, 0xb4, 0xa8, 0xe7, 0xb9, 0x15,
0x53, 0x16, 0x52, 0xcf, 0x5f, 0x01, 0xc4, 0x4f, 0xb8, 0xab, 0x9b, 0x5d, 0x07, 0xf7, 0x2c, 0x53,
0x63, 0x67, 0x5f, 0x54, 0x9a, 0xfc, 0x4b, 0xc7, 0xdc, 0x60, 0x70, 0xf4, 0x1a, 0x14, 0xdc, 0xfd,
0x21, 0xf3, 0xe2, 0x8d, 0x44, 0xef, 0xe8, 0xf3, 0xb5, 0xb9, 0x3f, 0xc4, 0x0a, 0x45, 0x47, 0x0b,
0x00, 0x84, 0x94, 0x6b, 0xab, 0x8f, 0x78, 0x48, 0x2c, 0x28, 0x01, 0x08, 0xd1, 0x66, 0x4f, 0x86,
0x33, 0x2c, 0x74, 0xf0, 0xa1, 0xfc, 0xa7, 0x1c, 0x34, 0x7d, 0x92, 0x0a, 0x76, 0x46, 0x03, 0x37,
0x55, 0x7e, 0xe3, 0x8b, 0xc1, 0x49, 0x79, 0xc3, 0xbb, 0x50, 0xe5, 0xe7, 0x79, 0x00, 0x7d, 0x00,
0x36, 0x65, 0x75, 0x8c, 0x82, 0x16, 0x9f, 0x90, 0x82, 0x96, 0x0e, 0xa8, 0xa0, 0xf2, 0x06, 0xcc,
0x7b, 0x7e, 0xcf, 0x47, 0x58, 0xc3, 0xae, 0x3a, 0x26, 0xe1, 0x38, 0x03, 0x55, 0x16, 0xcf, 0x58,
0x20, 0x67, 0xa9, 0x3a, 0x6c, 0x89, 0x0a, 0x57, 0xfe, 0x2e, 0x1c, 0xa3, 0x7e, 0x23, 0xda, 0xca,
0xcd, 0xd2, 0xe6, 0x97, 0x45, 0x21, 0x40, 0x92, 0x7e, 0xa6, 0xdd, 0x15, 0x25, 0x04, 0x93, 0x57,
0xe1, 0xb9, 0x08, 0xfd, 0x43, 0xc4, 0x05, 0x92, 0x0a, 0xcd, 0x6f, 0x84, 0x2f, 0xc5, 0xa7, 0x8f,
0x7e, 0xa7, 0x45, 0xe7, 0xb6, 0xab, 0x6b, 0x51, 0xfd, 0xd2, 0xd0, 0x3b, 0x50, 0x31, 0xf1, 0x5e,
0x37, 0xe8, 0x7c, 0x33, 0x34, 0xe8, 0xca, 0x26, 0xde, 0xa3, 0xbf, 0xe4, 0xbb, 0x70, 0x3c, 0xc6,
0xea, 0x61, 0xf6, 0xfe, 0x67, 0x09, 0x4e, 0x2c, 0xdb, 0xd6, 0xf0, 0x3d, 0xdd, 0x76, 0x47, 0xea,
0x20, 0x7c, 0xcf, 0xf5, 0x74, 0xca, 0xb8, 0x3b, 0x81, 0x30, 0xcc, 0xfc, 0xf2, 0x95, 0x04, 0x75,
0x8d, 0x33, 0xc5, 0x37, 0x1d, 0x08, 0xda, 0xff, 0xca, 0x27, 0x31, 0xcf, 0xf1, 0x26, 0x04, 0x9b,
0x2c, 0x59, 0x4a, 0x62, 0xd7, 0x27, 0x3f, 0x6d, 0xd7, 0x27, 0xc5, 0xf2, 0x0b, 0x4f, 0xc8, 0xf2,
0x0f, 0x5c, 0x86, 0xdc, 0x81, 0x70, 0x47, 0x8e, 0xba, 0xdc, 0xa9, 0x5a, 0x79, 0x4b, 0x00, 0x7e,
0x77, 0x8a, 0xbf, 0x69, 0xca, 0x42, 0x26, 0x30, 0x8b, 0x9c, 0x96, 0xf0, 0xb2, 0xb4, 0xab, 0x1c,
0xea, 0x97, 0xdc, 0x83, 0x76, 0x92, 0x96, 0x1e, 0x46, 0xf3, 0x3f, 0xcf, 0x01, 0x74, 0xc4, 0x33,
0xb8, 0xe9, 0x32, 0xca, 0xf3, 0x50, 0xf7, 0x15, 0xc6, 0xb7, 0xf7, 0xa0, 0x16, 0x69, 0xc4, 0x24,
0x44, 0x62, 0x4b, 0x70, 0x62, 0xc9, 0xae, 0x46, 0xe9, 0x04, 0xac, 0x86, 0x29, 0x45, 0xc4, 0xe9,
0xa1, 0x93, 0x50, 0xb1, 0xad, 0xbd, 0x2e, 0x31, 0x33, 0xcd, 0x7b, 0xe7, 0x67, 0x5b, 0x7b, 0xc4,
0xf8, 0x34, 0x74, 0x1c, 0x66, 0x5c, 0xd5, 0xd9, 0x25, 0xf4, 0x4b, 0x81, 0xab, 0x56, 0x0d, 0x1d,
0x83, 0xe2, 0xb6, 0x3e, 0xc0, 0xec, 0x66, 0xaf, 0xa2, 0xb0, 0x01, 0x7a, 0xdd, 0x7b, 0x90, 0x52,
0xce, 0x7c, 0x9d, 0xce, 0xde, 0xa4, 0x7c, 0x29, 0xc1, 0xac, 0x2f, 0x35, 0xea, 0x80, 0x88, 0x4f,
0xa3, 0xfe, 0xec, 0xa6, 0xa5, 0x31, 0x57, 0xd1, 0x48, 0xb9, 0x62, 0x61, 0x13, 0x99, 0xd7, 0xf2,
0xa7, 0x8c, 0xcb, 0xcb, 0xc9, 0xbe, 0xc8, 0xa6, 0x75, 0xcd, 0xbb, 0xe1, 0x29, 0xd9, 0xd6, 0x5e,
0x47, 0x13, 0xd2, 0x60, 0x8f, 0xf8, 0x58, 0x16, 0x4a, 0xa4, 0x71, 0x93, 0xbe, 0xe3, 0x3b, 0x0f,
0x75, 0x6c, 0xdb, 0x96, 0xdd, 0x35, 0xb0, 0xe3, 0xa8, 0x7d, 0xcc, 0x93, 0xae, 0x1a, 0x05, 0xae,
0x31, 0x98, 0xfc, 0x45, 0x1e, 0x1a, 0xfe, 0x56, 0xbc, 0x7b, 0x1d, 0x5d, 0xf3, 0xee, 0x75, 0x74,
0x72, 0x74, 0x60, 0x33, 0x57, 0x28, 0x0e, 0x77, 0x29, 0xd7, 0x92, 0x94, 0x0a, 0x87, 0x76, 0x34,
0x12, 0x0b, 0x89, 0x91, 0x99, 0x96, 0x86, 0xfd, 0xc3, 0x05, 0x0f, 0xc4, 0xcf, 0x36, 0xa4, 0x23,
0x85, 0x0c, 0x3a, 0x52, 0xcc, 0xa0, 0x23, 0xa5, 0x04, 0x1d, 0x99, 0x87, 0xd2, 0xd6, 0xa8, 0xb7,
0x8b, 0x5d, 0x9e, 0x22, 0xf1, 0x51, 0x58, 0x77, 0xca, 0x11, 0xdd, 0x11, 0x2a, 0x52, 0x09, 0xaa,
0xc8, 0x49, 0xa8, 0xb0, 0x0b, 0x86, 0xae, 0xeb, 0xd0, 0x4e, 0x6b, 0x5e, 0x29, 0x33, 0xc0, 0xa6,
0x83, 0xde, 0xf0, 0xea, 0x87, 0x6a, 0x92, 0xb1, 0x53, 0xaf, 0x13, 0xd1, 0x12, 0xaf, 0x7a, 0xb8,
0x00, 0x0d, 0xfa, 0xc8, 0xf9, 0xe1, 0x08, 0xdb, 0xfb, 0xea, 0xd6, 0x00, 0xb7, 0x6a, 0x94, 0x9d,
0x3a, 0x81, 0xde, 0xf3, 0x80, 0x44, 0x20, 0x14, 0x4d, 0x37, 0x35, 0xfc, 0x18, 0x6b, 0xad, 0x3a,
0x45, 0xa2, 0xa2, 0xee, 0x30, 0x90, 0xfc, 0x01, 0x20, 0x7f, 0x8d, 0xc3, 0x55, 0x86, 0x91, 0x43,
0xcc, 0x45, 0x0f, 0x51, 0xfe, 0x9d, 0x04, 0x73, 0xc1, 0xc5, 0xa6, 0x0d, 0x8f, 0xef, 0x40, 0x95,
0x75, 0xa4, 0xbb, 0xc4, 0x3c, 0x79, 0x6d, 0x78, 0x7a, 0xac, 0xf4, 0x14, 0xf0, 0x1f, 0xeb, 0x12,
0x25, 0xd8, 0xb3, 0xec, 0x5d, 0xdd, 0xec, 0x77, 0x09, 0x67, 0x9e, 0x51, 0xd4, 0x38, 0xf0, 0x2e,
0x81, 0xc9, 0x9f, 0x4a, 0xb0, 0x70, 0x7f, 0xa8, 0xa9, 0x2e, 0x0e, 0xe4, 0x09, 0x87, 0x7d, 0xff,
0xf3, 0x9a, 0xf7, 0x00, 0x27, 0x97, 0xad, 0xab, 0xca, 0xb0, 0xe5, 0x35, 0x38, 0xa1, 0x60, 0x07,
0x9b, 0x5a, 0xe8, 0xe3, 0xb4, 0x5c, 0xc8, 0x43, 0x68, 0x27, 0x91, 0x3b, 0xcc, 0xd9, 0xb3, 0x84,
0xad, 0x6b, 0x13, 0xb2, 0x2e, 0xf7, 0x3f, 0x24, 0x4f, 0xa0, 0xeb, 0xb8, 0xf2, 0xbf, 0x25, 0x98,
0xbb, 0xa1, 0x79, 0xeb, 0x3d, 0xb5, 0xbc, 0x30, 0x9a, 0x37, 0xe5, 0xe3, 0x79, 0xd3, 0x93, 0x72,
0x24, 0xdc, 0xa5, 0x9a, 0x23, 0xc3, 0x0b, 0x15, 0x36, 0xbd, 0xdf, 0x95, 0xb7, 0xc5, 0xa5, 0x9f,
0x82, 0xb7, 0xb1, 0x8d, 0xcd, 0x1e, 0x5e, 0xb5, 0x7a, 0xbb, 0x81, 0x57, 0x3c, 0x52, 0xf0, 0x15,
0xcf, 0xb4, 0xaf, 0x82, 0x2e, 0xff, 0x5c, 0x82, 0xb9, 0x58, 0x77, 0x01, 0x35, 0x00, 0xee, 0x9b,
0x3d, 0xde, 0x76, 0x69, 0x1e, 0x41, 0x35, 0x28, 0x7b, 0x4d, 0x98, 0xa6, 0x84, 0xaa, 0x30, 0xb3,
0x69, 0x51, 0xec, 0x66, 0x0e, 0x35, 0xa1, 0xc6, 0x26, 0x8e, 0x7a, 0x3d, 0xec, 0x38, 0xcd, 0xbc,
0x80, 0xdc, 0x56, 0xf5, 0xc1, 0xc8, 0xc6, 0xcd, 0x02, 0xaa, 0x43, 0x65, 0xd3, 0xe2, 0x6f, 0xa0,
0x9a, 0x45, 0x84, 0xa0, 0xe1, 0x3d, 0x88, 0xe2, 0x93, 0x4a, 0x01, 0x98, 0x37, 0x6d, 0xe6, 0xf2,
0x76, 0xb0, 0x0e, 0x27, 0xc5, 0x29, 0x3a, 0x0e, 0x47, 0xef, 0x9b, 0x1a, 0xde, 0xd6, 0x4d, 0xac,
0xf9, 0x9f, 0x9a, 0x47, 0xd0, 0x51, 0x98, 0xed, 0x98, 0x26, 0xb6, 0x03, 0x40, 0x89, 0x00, 0xd7,
0xb0, 0xdd, 0xc7, 0x01, 0x60, 0x0e, 0xcd, 0x41, 0x7d, 0x4d, 0x7f, 0x1c, 0x00, 0xe5, 0x17, 0xff,
0x79, 0x1c, 0x2a, 0xcb, 0xaa, 0xab, 0xde, 0xb4, 0x2c, 0x5b, 0x43, 0x43, 0x40, 0xf4, 0x05, 0xa1,
0x31, 0xb4, 0x4c, 0xf1, 0x2e, 0x17, 0xbd, 0x92, 0x92, 0x42, 0xc5, 0x51, 0xb9, 0x5a, 0xb6, 0x2f,
0xa6, 0xcc, 0x88, 0xa0, 0xcb, 0x47, 0x90, 0x41, 0x57, 0x24, 0xc5, 0xfd, 0xa6, 0xde, 0xdb, 0xf5,
0x9e, 0x16, 0x8c, 0x59, 0x31, 0x82, 0xea, 0xad, 0x18, 0x79, 0xee, 0xcb, 0x07, 0xec, 0x99, 0xa7,
0x67, 0x97, 0xf2, 0x11, 0xf4, 0x10, 0x8e, 0xad, 0xe0, 0x80, 0x1f, 0xf2, 0x16, 0x5c, 0x4c, 0x5f,
0x30, 0x86, 0x7c, 0xc0, 0x25, 0x57, 0xa1, 0x48, 0x3b, 0x79, 0x28, 0xc9, 0x55, 0x05, 0xff, 0xfc,
0xd2, 0x3e, 0x9b, 0x8e, 0x20, 0xa8, 0x7d, 0x00, 0xb3, 0x91, 0xc7, 0xf7, 0xe8, 0xc5, 0x84, 0x69,
0xc9, 0x7f, 0xa3, 0x68, 0x5f, 0xce, 0x82, 0x2a, 0xd6, 0xea, 0x43, 0x23, 0xfc, 0xfa, 0x10, 0x5d,
0x4a, 0x98, 0x9f, 0xf8, 0x6e, 0xba, 0xfd, 0x62, 0x06, 0x4c, 0xb1, 0x90, 0x01, 0xcd, 0xe8, 0x63,
0x70, 0x74, 0x79, 0x2c, 0x81, 0xb0, 0xba, 0xbd, 0x94, 0x09, 0x57, 0x2c, 0xb7, 0x4f, 0x95, 0x20,
0xf6, 0xbe, 0x18, 0x5d, 0x4d, 0x26, 0x93, 0xf6, 0xf0, 0xb9, 0x7d, 0x2d, 0x33, 0xbe, 0x58, 0xfa,
0x7b, 0xec, 0x06, 0x21, 0xe9, 0x8d, 0x2e, 0x7a, 0x35, 0x99, 0xdc, 0x98, 0xc7, 0xc5, 0xed, 0xc5,
0x83, 0x4c, 0x11, 0x4c, 0x7c, 0x44, 0x5b, 0xff, 0x09, 0xaf, 0x5c, 0xa3, 0x76, 0xe7, 0xd1, 0x4b,
0x7f, 0xc0, 0xdb, 0x7e, 0xf5, 0x00, 0x33, 0x04, 0x03, 0x56, 0xf4, 0xb5, 0xbd, 0x67, 0x86, 0xd7,
0x26, 0x6a, 0xcd, 0x74, 0x36, 0xf8, 0x3e, 0xcc, 0x46, 0x1e, 0x71, 0x24, 0x5a, 0x4d, 0xf2, 0x43,
0x8f, 0xf6, 0xb8, 0xf0, 0xcd, 0x4c, 0x32, 0x72, 0x93, 0x82, 0x52, 0xb4, 0x3f, 0xe1, 0xb6, 0xa5,
0x7d, 0x39, 0x0b, 0xaa, 0xd8, 0x88, 0x43, 0xdd, 0x65, 0xe4, 0x36, 0x02, 0x5d, 0x49, 0xa6, 0x91,
0x7c, 0x93, 0xd2, 0x7e, 0x39, 0x23, 0xb6, 0x58, 0xb4, 0x0b, 0xb0, 0x82, 0xdd, 0x35, 0xec, 0xda,
0x44, 0x47, 0x2e, 0x26, 0x8a, 0xdc, 0x47, 0xf0, 0x96, 0x79, 0x61, 0x22, 0x9e, 0x58, 0xe0, 0x5b,
0x80, 0xbc, 0x10, 0x1b, 0x78, 0x42, 0x74, 0x7e, 0x6c, 0xc3, 0x96, 0x75, 0x57, 0x27, 0x9d, 0xcd,
0x43, 0x68, 0xae, 0xa9, 0x26, 0x29, 0xd5, 0x7d, 0xba, 0x57, 0x12, 0x19, 0x8b, 0xa2, 0xa5, 0x48,
0x2b, 0x15, 0x5b, 0x6c, 0x66, 0x4f, 0xc4, 0x50, 0x55, 0x98, 0x20, 0x8e, 0xfa, 0x16, 0x5f, 0x1a,
0x11, 0xc4, 0x14, 0xdf, 0x32, 0x06, 0x5f, 0x2c, 0xfc, 0xb1, 0x44, 0xff, 0xa7, 0x11, 0x41, 0x78,
0xa0, 0xbb, 0x3b, 0xeb, 0x03, 0xd5, 0x74, 0xb2, 0xb0, 0x40, 0x11, 0x0f, 0xc0, 0x02, 0xc7, 0x17,
0x2c, 0x68, 0x50, 0x0f, 0xf5, 0x43, 0x51, 0xd2, 0x3b, 0xa0, 0xa4, 0x8e, 0x6c, 0xfb, 0xd2, 0x64,
0x44, 0xb1, 0xca, 0x0e, 0xd4, 0x3d, 0x7d, 0x65, 0xc2, 0x7d, 0x31, 0x8d, 0x53, 0x1f, 0x27, 0xc5,
0xdc, 0x92, 0x51, 0x83, 0xe6, 0x16, 0x6f, 0xf7, 0xa0, 0x6c, 0x6d, 0xc2, 0x71, 0xe6, 0x96, 0xde,
0x43, 0x62, 0xfe, 0x24, 0xd2, 0x5a, 0x4d, 0x76, 0x56, 0x89, 0x9d, 0xe2, 0x44, 0x7f, 0x92, 0xd2,
0xa9, 0x95, 0x8f, 0xa0, 0x07, 0x50, 0xe2, 0x7f, 0xd0, 0x7c, 0x7e, 0x7c, 0xf1, 0xc7, 0xa9, 0x5f,
0x98, 0x80, 0x25, 0x08, 0xef, 0xc2, 0xf1, 0x94, 0xd2, 0x2f, 0x31, 0xce, 0x8d, 0x2f, 0x13, 0x27,
0x59, 0xb9, 0x0a, 0x28, 0xfe, 0x2f, 0x88, 0xc4, 0x63, 0x4a, 0xfd, 0xb3, 0x44, 0x86, 0x25, 0xe2,
0x7f, 0x64, 0x48, 0x5c, 0x22, 0xf5, 0xff, 0x0e, 0x93, 0x96, 0xb8, 0x07, 0xe0, 0x17, 0x78, 0x89,
0xe7, 0x11, 0xab, 0xff, 0x26, 0x90, 0x5c, 0xfc, 0x4f, 0x09, 0xca, 0xde, 0xab, 0x9b, 0x67, 0x90,
0xdc, 0x3f, 0x83, 0x6c, 0xfb, 0x7d, 0x98, 0x8d, 0x3c, 0xdf, 0x4f, 0x34, 0x9e, 0xe4, 0x27, 0xfe,
0x93, 0x4e, 0xe8, 0x01, 0xff, 0x4b, 0xb8, 0x08, 0xbc, 0x2f, 0xa4, 0x65, 0xec, 0xd1, 0x98, 0x3b,
0x81, 0xf0, 0x53, 0x8f, 0xb0, 0x77, 0x01, 0x02, 0x11, 0x70, 0xfc, 0x55, 0x28, 0x71, 0xea, 0x93,
0x18, 0x5e, 0x3b, 0xa0, 0xdf, 0x98, 0x40, 0xce, 0x21, 0xd6, 0x15, 0x6d, 0xa7, 0xa4, 0x58, 0x57,
0x4a, 0x13, 0x27, 0xd1, 0xcf, 0xa6, 0xf7, 0x68, 0x9e, 0x8a, 0xbd, 0x2d, 0x5d, 0xff, 0xf6, 0xab,
0x7d, 0xdd, 0xdd, 0x19, 0x6d, 0x91, 0x2f, 0xd7, 0x18, 0xea, 0xcb, 0xba, 0xc5, 0x7f, 0x5d, 0xf3,
0x14, 0xfd, 0x1a, 0x9d, 0x7d, 0x8d, 0xac, 0x31, 0xdc, 0xda, 0x2a, 0xd1, 0xd1, 0xf5, 0xff, 0x05,
0x00, 0x00, 0xff, 0xff, 0x64, 0x37, 0x8c, 0x0d, 0x75, 0x41, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@ -55,6 +55,28 @@ message TimeTickMsg {
common.MsgBase base = 1;
}
message GetStatisticsRequest {
common.MsgBase base = 1;
// Not useful for now
int64 dbID = 2;
// The collection you want get statistics
int64 collectionID = 3;
// The partitions you want get statistics
repeated int64 partitionIDs = 4;
// timestamp of the statistics
uint64 travel_timestamp = 5;
uint64 guarantee_timestamp = 6;
uint64 timeout_timestamp = 7;
}
message GetStatisticsResponse {
common.MsgBase base = 1;
// Contain error_code and reason
common.Status status = 2;
// Collection statistics data. Contain pairs like {"row_count": "1"}
repeated common.KeyValuePair stats = 3;
}
message CreateCollectionRequest {
common.MsgBase base = 1;
string db_name = 2;

View File

@ -498,6 +498,154 @@ func (m *TimeTickMsg) GetBase() *commonpb.MsgBase {
return nil
}
type GetStatisticsRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
// Not useful for now
DbID int64 `protobuf:"varint,2,opt,name=dbID,proto3" json:"dbID,omitempty"`
// The collection you want get statistics
CollectionID int64 `protobuf:"varint,3,opt,name=collectionID,proto3" json:"collectionID,omitempty"`
// The partitions you want get statistics
PartitionIDs []int64 `protobuf:"varint,4,rep,packed,name=partitionIDs,proto3" json:"partitionIDs,omitempty"`
// timestamp of the statistics
TravelTimestamp uint64 `protobuf:"varint,5,opt,name=travel_timestamp,json=travelTimestamp,proto3" json:"travel_timestamp,omitempty"`
GuaranteeTimestamp uint64 `protobuf:"varint,6,opt,name=guarantee_timestamp,json=guaranteeTimestamp,proto3" json:"guarantee_timestamp,omitempty"`
TimeoutTimestamp uint64 `protobuf:"varint,7,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetStatisticsRequest) Reset() { *m = GetStatisticsRequest{} }
func (m *GetStatisticsRequest) String() string { return proto.CompactTextString(m) }
func (*GetStatisticsRequest) ProtoMessage() {}
func (*GetStatisticsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{10}
}
func (m *GetStatisticsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetStatisticsRequest.Unmarshal(m, b)
}
func (m *GetStatisticsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetStatisticsRequest.Marshal(b, m, deterministic)
}
func (m *GetStatisticsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetStatisticsRequest.Merge(m, src)
}
func (m *GetStatisticsRequest) XXX_Size() int {
return xxx_messageInfo_GetStatisticsRequest.Size(m)
}
func (m *GetStatisticsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetStatisticsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetStatisticsRequest proto.InternalMessageInfo
func (m *GetStatisticsRequest) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *GetStatisticsRequest) GetDbID() int64 {
if m != nil {
return m.DbID
}
return 0
}
func (m *GetStatisticsRequest) GetCollectionID() int64 {
if m != nil {
return m.CollectionID
}
return 0
}
func (m *GetStatisticsRequest) GetPartitionIDs() []int64 {
if m != nil {
return m.PartitionIDs
}
return nil
}
func (m *GetStatisticsRequest) GetTravelTimestamp() uint64 {
if m != nil {
return m.TravelTimestamp
}
return 0
}
func (m *GetStatisticsRequest) GetGuaranteeTimestamp() uint64 {
if m != nil {
return m.GuaranteeTimestamp
}
return 0
}
func (m *GetStatisticsRequest) GetTimeoutTimestamp() uint64 {
if m != nil {
return m.TimeoutTimestamp
}
return 0
}
type GetStatisticsResponse struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
// Contain error_code and reason
Status *commonpb.Status `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
// Collection statistics data. Contain pairs like {"row_count": "1"}
Stats []*commonpb.KeyValuePair `protobuf:"bytes,3,rep,name=stats,proto3" json:"stats,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetStatisticsResponse) Reset() { *m = GetStatisticsResponse{} }
func (m *GetStatisticsResponse) String() string { return proto.CompactTextString(m) }
func (*GetStatisticsResponse) ProtoMessage() {}
func (*GetStatisticsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{11}
}
func (m *GetStatisticsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetStatisticsResponse.Unmarshal(m, b)
}
func (m *GetStatisticsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetStatisticsResponse.Marshal(b, m, deterministic)
}
func (m *GetStatisticsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetStatisticsResponse.Merge(m, src)
}
func (m *GetStatisticsResponse) XXX_Size() int {
return xxx_messageInfo_GetStatisticsResponse.Size(m)
}
func (m *GetStatisticsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetStatisticsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetStatisticsResponse proto.InternalMessageInfo
func (m *GetStatisticsResponse) GetBase() *commonpb.MsgBase {
if m != nil {
return m.Base
}
return nil
}
func (m *GetStatisticsResponse) GetStatus() *commonpb.Status {
if m != nil {
return m.Status
}
return nil
}
func (m *GetStatisticsResponse) GetStats() []*commonpb.KeyValuePair {
if m != nil {
return m.Stats
}
return nil
}
type CreateCollectionRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
DbName string `protobuf:"bytes,2,opt,name=db_name,json=dbName,proto3" json:"db_name,omitempty"`
@ -519,7 +667,7 @@ func (m *CreateCollectionRequest) Reset() { *m = CreateCollectionRequest
func (m *CreateCollectionRequest) String() string { return proto.CompactTextString(m) }
func (*CreateCollectionRequest) ProtoMessage() {}
func (*CreateCollectionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{10}
return fileDescriptor_41f4a519b878ee3b, []int{12}
}
func (m *CreateCollectionRequest) XXX_Unmarshal(b []byte) error {
@ -625,7 +773,7 @@ func (m *DropCollectionRequest) Reset() { *m = DropCollectionRequest{} }
func (m *DropCollectionRequest) String() string { return proto.CompactTextString(m) }
func (*DropCollectionRequest) ProtoMessage() {}
func (*DropCollectionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{11}
return fileDescriptor_41f4a519b878ee3b, []int{13}
}
func (m *DropCollectionRequest) XXX_Unmarshal(b []byte) error {
@ -698,7 +846,7 @@ func (m *CreatePartitionRequest) Reset() { *m = CreatePartitionRequest{}
func (m *CreatePartitionRequest) String() string { return proto.CompactTextString(m) }
func (*CreatePartitionRequest) ProtoMessage() {}
func (*CreatePartitionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{12}
return fileDescriptor_41f4a519b878ee3b, []int{14}
}
func (m *CreatePartitionRequest) XXX_Unmarshal(b []byte) error {
@ -785,7 +933,7 @@ func (m *DropPartitionRequest) Reset() { *m = DropPartitionRequest{} }
func (m *DropPartitionRequest) String() string { return proto.CompactTextString(m) }
func (*DropPartitionRequest) ProtoMessage() {}
func (*DropPartitionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{13}
return fileDescriptor_41f4a519b878ee3b, []int{15}
}
func (m *DropPartitionRequest) XXX_Unmarshal(b []byte) error {
@ -869,7 +1017,7 @@ func (m *CreateAliasRequest) Reset() { *m = CreateAliasRequest{} }
func (m *CreateAliasRequest) String() string { return proto.CompactTextString(m) }
func (*CreateAliasRequest) ProtoMessage() {}
func (*CreateAliasRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{14}
return fileDescriptor_41f4a519b878ee3b, []int{16}
}
func (m *CreateAliasRequest) XXX_Unmarshal(b []byte) error {
@ -931,7 +1079,7 @@ func (m *DropAliasRequest) Reset() { *m = DropAliasRequest{} }
func (m *DropAliasRequest) String() string { return proto.CompactTextString(m) }
func (*DropAliasRequest) ProtoMessage() {}
func (*DropAliasRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{15}
return fileDescriptor_41f4a519b878ee3b, []int{17}
}
func (m *DropAliasRequest) XXX_Unmarshal(b []byte) error {
@ -987,7 +1135,7 @@ func (m *AlterAliasRequest) Reset() { *m = AlterAliasRequest{} }
func (m *AlterAliasRequest) String() string { return proto.CompactTextString(m) }
func (*AlterAliasRequest) ProtoMessage() {}
func (*AlterAliasRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{16}
return fileDescriptor_41f4a519b878ee3b, []int{18}
}
func (m *AlterAliasRequest) XXX_Unmarshal(b []byte) error {
@ -1054,7 +1202,7 @@ func (m *CreateIndexRequest) Reset() { *m = CreateIndexRequest{} }
func (m *CreateIndexRequest) String() string { return proto.CompactTextString(m) }
func (*CreateIndexRequest) ProtoMessage() {}
func (*CreateIndexRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{17}
return fileDescriptor_41f4a519b878ee3b, []int{19}
}
func (m *CreateIndexRequest) XXX_Unmarshal(b []byte) error {
@ -1157,7 +1305,7 @@ func (m *InsertRequest) Reset() { *m = InsertRequest{} }
func (m *InsertRequest) String() string { return proto.CompactTextString(m) }
func (*InsertRequest) ProtoMessage() {}
func (*InsertRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{18}
return fileDescriptor_41f4a519b878ee3b, []int{20}
}
func (m *InsertRequest) XXX_Unmarshal(b []byte) error {
@ -1310,7 +1458,7 @@ func (m *SearchRequest) Reset() { *m = SearchRequest{} }
func (m *SearchRequest) String() string { return proto.CompactTextString(m) }
func (*SearchRequest) ProtoMessage() {}
func (*SearchRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{19}
return fileDescriptor_41f4a519b878ee3b, []int{21}
}
func (m *SearchRequest) XXX_Unmarshal(b []byte) error {
@ -1466,7 +1614,7 @@ func (m *SearchResults) Reset() { *m = SearchResults{} }
func (m *SearchResults) String() string { return proto.CompactTextString(m) }
func (*SearchResults) ProtoMessage() {}
func (*SearchResults) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{20}
return fileDescriptor_41f4a519b878ee3b, []int{22}
}
func (m *SearchResults) XXX_Unmarshal(b []byte) error {
@ -1591,7 +1739,7 @@ func (m *RetrieveRequest) Reset() { *m = RetrieveRequest{} }
func (m *RetrieveRequest) String() string { return proto.CompactTextString(m) }
func (*RetrieveRequest) ProtoMessage() {}
func (*RetrieveRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{21}
return fileDescriptor_41f4a519b878ee3b, []int{23}
}
func (m *RetrieveRequest) XXX_Unmarshal(b []byte) error {
@ -1700,7 +1848,7 @@ func (m *RetrieveResults) Reset() { *m = RetrieveResults{} }
func (m *RetrieveResults) String() string { return proto.CompactTextString(m) }
func (*RetrieveResults) ProtoMessage() {}
func (*RetrieveResults) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{22}
return fileDescriptor_41f4a519b878ee3b, []int{24}
}
func (m *RetrieveResults) XXX_Unmarshal(b []byte) error {
@ -1799,7 +1947,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteRequest) ProtoMessage() {}
func (*DeleteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{23}
return fileDescriptor_41f4a519b878ee3b, []int{25}
}
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
@ -1920,7 +2068,7 @@ func (m *LoadIndex) Reset() { *m = LoadIndex{} }
func (m *LoadIndex) String() string { return proto.CompactTextString(m) }
func (*LoadIndex) ProtoMessage() {}
func (*LoadIndex) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{24}
return fileDescriptor_41f4a519b878ee3b, []int{26}
}
func (m *LoadIndex) XXX_Unmarshal(b []byte) error {
@ -1995,7 +2143,7 @@ func (m *IndexStats) Reset() { *m = IndexStats{} }
func (m *IndexStats) String() string { return proto.CompactTextString(m) }
func (*IndexStats) ProtoMessage() {}
func (*IndexStats) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{25}
return fileDescriptor_41f4a519b878ee3b, []int{27}
}
func (m *IndexStats) XXX_Unmarshal(b []byte) error {
@ -2043,7 +2191,7 @@ func (m *FieldStats) Reset() { *m = FieldStats{} }
func (m *FieldStats) String() string { return proto.CompactTextString(m) }
func (*FieldStats) ProtoMessage() {}
func (*FieldStats) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{26}
return fileDescriptor_41f4a519b878ee3b, []int{28}
}
func (m *FieldStats) XXX_Unmarshal(b []byte) error {
@ -2099,7 +2247,7 @@ func (m *SegmentStats) Reset() { *m = SegmentStats{} }
func (m *SegmentStats) String() string { return proto.CompactTextString(m) }
func (*SegmentStats) ProtoMessage() {}
func (*SegmentStats) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{27}
return fileDescriptor_41f4a519b878ee3b, []int{29}
}
func (m *SegmentStats) XXX_Unmarshal(b []byte) error {
@ -2162,7 +2310,7 @@ func (m *MsgPosition) Reset() { *m = MsgPosition{} }
func (m *MsgPosition) String() string { return proto.CompactTextString(m) }
func (*MsgPosition) ProtoMessage() {}
func (*MsgPosition) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{28}
return fileDescriptor_41f4a519b878ee3b, []int{30}
}
func (m *MsgPosition) XXX_Unmarshal(b []byte) error {
@ -2225,7 +2373,7 @@ func (m *ChannelTimeTickMsg) Reset() { *m = ChannelTimeTickMsg{} }
func (m *ChannelTimeTickMsg) String() string { return proto.CompactTextString(m) }
func (*ChannelTimeTickMsg) ProtoMessage() {}
func (*ChannelTimeTickMsg) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{29}
return fileDescriptor_41f4a519b878ee3b, []int{31}
}
func (m *ChannelTimeTickMsg) XXX_Unmarshal(b []byte) error {
@ -2291,7 +2439,7 @@ func (m *CredentialInfo) Reset() { *m = CredentialInfo{} }
func (m *CredentialInfo) String() string { return proto.CompactTextString(m) }
func (*CredentialInfo) ProtoMessage() {}
func (*CredentialInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{30}
return fileDescriptor_41f4a519b878ee3b, []int{32}
}
func (m *CredentialInfo) XXX_Unmarshal(b []byte) error {
@ -2359,7 +2507,7 @@ func (m *ListPolicyRequest) Reset() { *m = ListPolicyRequest{} }
func (m *ListPolicyRequest) String() string { return proto.CompactTextString(m) }
func (*ListPolicyRequest) ProtoMessage() {}
func (*ListPolicyRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{31}
return fileDescriptor_41f4a519b878ee3b, []int{33}
}
func (m *ListPolicyRequest) XXX_Unmarshal(b []byte) error {
@ -2400,7 +2548,7 @@ func (m *ListPolicyResponse) Reset() { *m = ListPolicyResponse{} }
func (m *ListPolicyResponse) String() string { return proto.CompactTextString(m) }
func (*ListPolicyResponse) ProtoMessage() {}
func (*ListPolicyResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_41f4a519b878ee3b, []int{32}
return fileDescriptor_41f4a519b878ee3b, []int{34}
}
func (m *ListPolicyResponse) XXX_Unmarshal(b []byte) error {
@ -2448,6 +2596,8 @@ func init() {
proto.RegisterType((*InitParams)(nil), "milvus.proto.internal.InitParams")
proto.RegisterType((*StringList)(nil), "milvus.proto.internal.StringList")
proto.RegisterType((*TimeTickMsg)(nil), "milvus.proto.internal.TimeTickMsg")
proto.RegisterType((*GetStatisticsRequest)(nil), "milvus.proto.internal.GetStatisticsRequest")
proto.RegisterType((*GetStatisticsResponse)(nil), "milvus.proto.internal.GetStatisticsResponse")
proto.RegisterType((*CreateCollectionRequest)(nil), "milvus.proto.internal.CreateCollectionRequest")
proto.RegisterType((*DropCollectionRequest)(nil), "milvus.proto.internal.DropCollectionRequest")
proto.RegisterType((*CreatePartitionRequest)(nil), "milvus.proto.internal.CreatePartitionRequest")
@ -2476,136 +2626,139 @@ func init() {
func init() { proto.RegisterFile("internal.proto", fileDescriptor_41f4a519b878ee3b) }
var fileDescriptor_41f4a519b878ee3b = []byte{
// 2085 bytes of a gzipped FileDescriptorProto
// 2139 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1b, 0x49,
0x15, 0xdf, 0xd1, 0xc8, 0x96, 0xf4, 0x24, 0xcb, 0x72, 0xc7, 0x9b, 0x9d, 0x7c, 0xec, 0xae, 0x33,
0x2c, 0x60, 0x12, 0x36, 0x09, 0xde, 0xdd, 0xec, 0x16, 0x50, 0x84, 0xc4, 0x5a, 0x82, 0x2a, 0x1f,
0x98, 0x71, 0x48, 0x15, 0x5c, 0xa6, 0x5a, 0x9a, 0xb6, 0xdc, 0x64, 0x66, 0x7a, 0xd2, 0xdd, 0x63,
0x47, 0x39, 0x71, 0xe0, 0x04, 0x05, 0x37, 0x2e, 0x54, 0xc1, 0x99, 0xff, 0x80, 0x1b, 0x54, 0x71,
0xe2, 0xc4, 0x89, 0x0b, 0xff, 0x0a, 0xc5, 0x81, 0xea, 0x8f, 0x19, 0x8d, 0x64, 0xd9, 0x71, 0xbc,
0xb5, 0x6c, 0xa8, 0xda, 0xdb, 0xf4, 0x7b, 0xaf, 0x5f, 0xbf, 0x8f, 0xdf, 0x7b, 0xfd, 0x5a, 0x82,
0x2e, 0x4d, 0x25, 0xe1, 0x29, 0x8e, 0xaf, 0x67, 0x9c, 0x49, 0x86, 0xde, 0x4c, 0x68, 0x7c, 0x90,
0x0b, 0xb3, 0xba, 0x5e, 0x30, 0x2f, 0x76, 0x46, 0x2c, 0x49, 0x58, 0x6a, 0xc8, 0x17, 0x3b, 0x62,
0xb4, 0x4f, 0x12, 0x6c, 0x56, 0xfe, 0x5f, 0x1c, 0x58, 0xd9, 0x66, 0x49, 0xc6, 0x52, 0x92, 0xca,
0x41, 0xba, 0xc7, 0xd0, 0x79, 0x58, 0x4e, 0x59, 0x44, 0x06, 0x7d, 0xcf, 0xd9, 0x70, 0x36, 0xdd,
0xc0, 0xae, 0x10, 0x82, 0x3a, 0x67, 0x31, 0xf1, 0x6a, 0x1b, 0xce, 0x66, 0x2b, 0xd0, 0xdf, 0xe8,
0x36, 0x80, 0x90, 0x58, 0x92, 0x70, 0xc4, 0x22, 0xe2, 0xb9, 0x1b, 0xce, 0x66, 0x77, 0x6b, 0xe3,
0xfa, 0x42, 0x2b, 0xae, 0xef, 0x2a, 0xc1, 0x6d, 0x16, 0x91, 0xa0, 0x25, 0x8a, 0x4f, 0xf4, 0x7d,
0x00, 0xf2, 0x5c, 0x72, 0x1c, 0xd2, 0x74, 0x8f, 0x79, 0xf5, 0x0d, 0x77, 0xb3, 0xbd, 0x75, 0x65,
0x56, 0x81, 0x35, 0xfe, 0x3e, 0x99, 0x3c, 0xc1, 0x71, 0x4e, 0x76, 0x30, 0xe5, 0x41, 0x4b, 0x6f,
0x52, 0xe6, 0xfa, 0xff, 0x72, 0x60, 0xb5, 0x74, 0x40, 0x9f, 0x21, 0xd0, 0xb7, 0x61, 0x49, 0x1f,
0xa1, 0x3d, 0x68, 0x6f, 0xbd, 0x77, 0x8c, 0x45, 0x33, 0x7e, 0x07, 0x66, 0x0b, 0xfa, 0x09, 0x9c,
0x13, 0xf9, 0x70, 0x54, 0xb0, 0x42, 0x4d, 0x15, 0x5e, 0x4d, 0x9b, 0x76, 0x3a, 0x4d, 0xa8, 0xaa,
0xc0, 0x9a, 0xf4, 0x01, 0x2c, 0x2b, 0x4d, 0xb9, 0xd0, 0x51, 0x6a, 0x6f, 0x5d, 0x5a, 0xe8, 0xe4,
0xae, 0x16, 0x09, 0xac, 0xa8, 0x7f, 0x09, 0x2e, 0xdc, 0x23, 0x72, 0xce, 0xbb, 0x80, 0x3c, 0xcb,
0x89, 0x90, 0x96, 0xf9, 0x98, 0x26, 0xe4, 0x31, 0x1d, 0x3d, 0xdd, 0xde, 0xc7, 0x69, 0x4a, 0xe2,
0x82, 0xf9, 0x36, 0x5c, 0xba, 0x47, 0xf4, 0x06, 0x2a, 0x24, 0x1d, 0x89, 0x39, 0xf6, 0x9b, 0x70,
0xee, 0x1e, 0x91, 0xfd, 0x68, 0x8e, 0xfc, 0x04, 0x9a, 0x8f, 0x54, 0xb2, 0x15, 0x0c, 0x6e, 0x41,
0x03, 0x47, 0x11, 0x27, 0x42, 0xd8, 0x28, 0x5e, 0x5e, 0x68, 0xf1, 0x1d, 0x23, 0x13, 0x14, 0xc2,
0x8b, 0x60, 0xe2, 0xff, 0x1c, 0x60, 0x90, 0x52, 0xb9, 0x83, 0x39, 0x4e, 0xc4, 0xb1, 0x00, 0xeb,
0x43, 0x47, 0x48, 0xcc, 0x65, 0x98, 0x69, 0x39, 0x1b, 0xf2, 0x53, 0xa0, 0xa1, 0xad, 0xb7, 0x19,
0xed, 0xfe, 0x4f, 0x01, 0x76, 0x25, 0xa7, 0xe9, 0xf8, 0x01, 0x15, 0x52, 0x9d, 0x75, 0xa0, 0xe4,
0x94, 0x13, 0xee, 0x66, 0x2b, 0xb0, 0xab, 0x4a, 0x3a, 0x6a, 0xa7, 0x4f, 0xc7, 0x6d, 0x68, 0x17,
0xe1, 0x7e, 0x28, 0xc6, 0xe8, 0x26, 0xd4, 0x87, 0x58, 0x90, 0x13, 0xc3, 0xf3, 0x50, 0x8c, 0xef,
0x62, 0x41, 0x02, 0x2d, 0xe9, 0xff, 0xca, 0x85, 0xb7, 0xb6, 0x39, 0xd1, 0xe0, 0x8f, 0x63, 0x32,
0x92, 0x94, 0xa5, 0x36, 0xf6, 0xaf, 0xae, 0x0d, 0xbd, 0x05, 0x8d, 0x68, 0x18, 0xa6, 0x38, 0x29,
0x82, 0xbd, 0x1c, 0x0d, 0x1f, 0xe1, 0x84, 0xa0, 0xaf, 0x41, 0x77, 0x54, 0xea, 0x57, 0x14, 0x8d,
0xb9, 0x56, 0x30, 0x47, 0x45, 0xef, 0xc1, 0x4a, 0x86, 0xb9, 0xa4, 0xa5, 0x58, 0x5d, 0x8b, 0xcd,
0x12, 0x55, 0x42, 0xa3, 0xe1, 0xa0, 0xef, 0x2d, 0xe9, 0x64, 0xe9, 0x6f, 0xe4, 0x43, 0x67, 0xaa,
0x6b, 0xd0, 0xf7, 0x96, 0x35, 0x6f, 0x86, 0x86, 0x36, 0xa0, 0x5d, 0x2a, 0x1a, 0xf4, 0xbd, 0x86,
0x16, 0xa9, 0x92, 0x54, 0x72, 0x4c, 0x2f, 0xf2, 0x9a, 0x1b, 0xce, 0x66, 0x27, 0xb0, 0x2b, 0x74,
0x13, 0xce, 0x1d, 0x50, 0x2e, 0x73, 0x1c, 0x5b, 0x7c, 0x2a, 0x3b, 0x84, 0xd7, 0xd2, 0x19, 0x5c,
0xc4, 0x42, 0x5b, 0xb0, 0x9e, 0xed, 0x4f, 0x04, 0x1d, 0xcd, 0x6d, 0x01, 0xbd, 0x65, 0x21, 0xcf,
0xff, 0x9b, 0x03, 0x6f, 0xf6, 0x39, 0xcb, 0x5e, 0x8b, 0x54, 0x14, 0x41, 0xae, 0x9f, 0x10, 0xe4,
0xa5, 0xa3, 0x41, 0xf6, 0x7f, 0x53, 0x83, 0xf3, 0x06, 0x51, 0x3b, 0x45, 0x60, 0x3f, 0x07, 0x2f,
0xbe, 0x0e, 0xab, 0xd3, 0x53, 0x8d, 0xc0, 0x62, 0x37, 0xbe, 0x0a, 0xdd, 0x32, 0xc1, 0x46, 0xee,
0x7f, 0x0b, 0x29, 0xff, 0xd7, 0x35, 0x58, 0x57, 0x49, 0xfd, 0x32, 0x1a, 0x2a, 0x1a, 0x7f, 0x74,
0x00, 0x19, 0x74, 0xdc, 0x89, 0x29, 0x16, 0x5f, 0x64, 0x2c, 0xd6, 0x61, 0x09, 0x2b, 0x1b, 0x6c,
0x08, 0xcc, 0xc2, 0x17, 0xd0, 0x53, 0xd9, 0xfa, 0xbc, 0xac, 0x2b, 0x0f, 0x75, 0xab, 0x87, 0xfe,
0xc1, 0x81, 0xb5, 0x3b, 0xb1, 0x24, 0xfc, 0x35, 0x0d, 0xca, 0x5f, 0x6b, 0x45, 0xd6, 0x06, 0x69,
0x44, 0x9e, 0x7f, 0x91, 0x06, 0xbe, 0x0d, 0xb0, 0x47, 0x49, 0x1c, 0x55, 0xd1, 0xdb, 0xd2, 0x94,
0xcf, 0x84, 0x5c, 0x0f, 0x1a, 0x5a, 0x49, 0x89, 0xda, 0x62, 0xa9, 0x66, 0x00, 0x33, 0x0f, 0xda,
0x19, 0xa0, 0x79, 0xea, 0x19, 0x40, 0x6f, 0xb3, 0x33, 0xc0, 0x3f, 0xea, 0xb0, 0x32, 0x48, 0x05,
0xe1, 0xf2, 0xec, 0xc1, 0xbb, 0x0c, 0x2d, 0xb1, 0x8f, 0xb9, 0x76, 0xd4, 0x86, 0x6f, 0x4a, 0xa8,
0x86, 0xd6, 0x7d, 0x59, 0x68, 0xeb, 0xa7, 0x6c, 0x0e, 0x4b, 0x27, 0x35, 0x87, 0xe5, 0x13, 0x42,
0xdc, 0x78, 0x79, 0x73, 0x68, 0x1e, 0xbd, 0x7d, 0x95, 0x83, 0x64, 0x9c, 0xa8, 0xa1, 0xb5, 0xef,
0xb5, 0x34, 0x7f, 0x4a, 0x40, 0xef, 0x00, 0x48, 0x9a, 0x10, 0x21, 0x71, 0x92, 0x99, 0x7b, 0xb4,
0x1e, 0x54, 0x28, 0xea, 0xee, 0xe6, 0xec, 0x70, 0xd0, 0x17, 0x5e, 0x7b, 0xc3, 0x55, 0x43, 0x9c,
0x59, 0xa1, 0x0f, 0xa1, 0xc9, 0xd9, 0x61, 0x18, 0x61, 0x89, 0xbd, 0x8e, 0x4e, 0xde, 0x85, 0x85,
0xc1, 0xbe, 0x1b, 0xb3, 0x61, 0xd0, 0xe0, 0xec, 0xb0, 0x8f, 0x25, 0x46, 0xb7, 0xa1, 0xad, 0x11,
0x20, 0xcc, 0xc6, 0x15, 0xbd, 0xf1, 0x9d, 0xd9, 0x8d, 0xf6, 0xd9, 0xf2, 0x03, 0x25, 0xa7, 0x36,
0x05, 0x06, 0x9a, 0x42, 0x2b, 0xb8, 0x00, 0xcd, 0x34, 0x4f, 0x42, 0xce, 0x0e, 0x85, 0xd7, 0xdd,
0x70, 0x36, 0xeb, 0x41, 0x23, 0xcd, 0x93, 0x80, 0x1d, 0x0a, 0x74, 0x17, 0x1a, 0x07, 0x84, 0x0b,
0xca, 0x52, 0x6f, 0x55, 0x3f, 0x50, 0x36, 0x8f, 0x19, 0xe2, 0x0d, 0x62, 0x94, 0xba, 0x27, 0x46,
0x3e, 0x28, 0x36, 0xfa, 0xff, 0xac, 0xc3, 0xca, 0x2e, 0xc1, 0x7c, 0xb4, 0x7f, 0x76, 0x40, 0xad,
0xc3, 0x12, 0x27, 0xcf, 0x06, 0x7d, 0x0d, 0x26, 0x37, 0x30, 0x8b, 0x32, 0xbf, 0xee, 0x09, 0xf9,
0xad, 0x2f, 0xc8, 0xaf, 0x0f, 0x9d, 0x4a, 0x32, 0x85, 0xb7, 0xa4, 0xb3, 0x30, 0x43, 0x43, 0x3d,
0x70, 0x23, 0x11, 0x6b, 0xe8, 0xb4, 0x02, 0xf5, 0x89, 0xae, 0xc1, 0x5a, 0x16, 0xe3, 0x11, 0xd9,
0x67, 0x71, 0x44, 0x78, 0x38, 0xe6, 0x2c, 0xcf, 0x34, 0x7c, 0x3a, 0x41, 0xaf, 0xc2, 0xb8, 0xa7,
0xe8, 0xe8, 0x63, 0x68, 0x46, 0x22, 0x0e, 0xe5, 0x24, 0x23, 0x1a, 0x3f, 0xdd, 0x63, 0xdc, 0xec,
0x8b, 0xf8, 0xf1, 0x24, 0x23, 0x41, 0x23, 0x32, 0x1f, 0xe8, 0x26, 0xac, 0x0b, 0xc2, 0x29, 0x8e,
0xe9, 0x0b, 0x12, 0x85, 0xe4, 0x79, 0xc6, 0xc3, 0x2c, 0xc6, 0xa9, 0x06, 0x59, 0x27, 0x40, 0x53,
0xde, 0xa7, 0xcf, 0x33, 0xbe, 0x13, 0xe3, 0x14, 0x6d, 0x42, 0x8f, 0xe5, 0x32, 0xcb, 0x65, 0x68,
0x61, 0x40, 0x23, 0x8d, 0x39, 0x37, 0xe8, 0x1a, 0xba, 0xce, 0xba, 0x18, 0x44, 0xe8, 0x1b, 0xd0,
0x93, 0x1c, 0x1f, 0x90, 0x38, 0x2c, 0xc1, 0xe8, 0xb5, 0x75, 0xc2, 0x57, 0x0d, 0xfd, 0x71, 0x41,
0x46, 0x37, 0xe0, 0xdc, 0x38, 0xc7, 0x1c, 0xa7, 0x92, 0x90, 0x8a, 0x74, 0x47, 0x4b, 0xa3, 0x92,
0x35, 0xdd, 0x70, 0x0d, 0xd6, 0x94, 0x18, 0xcb, 0x65, 0x45, 0x7c, 0x45, 0x8b, 0xf7, 0x2c, 0x63,
0x2a, 0xdc, 0x85, 0x5a, 0xfa, 0x4c, 0x63, 0xcd, 0x0d, 0x6a, 0xe9, 0x33, 0x95, 0x48, 0xc9, 0xb2,
0xa7, 0x1a, 0x63, 0x6e, 0xa0, 0xbf, 0x55, 0x11, 0x25, 0x44, 0x72, 0x3a, 0x52, 0x61, 0xf1, 0x7a,
0x3a, 0x0f, 0x15, 0x8a, 0xff, 0x1f, 0x77, 0x0a, 0x2b, 0x91, 0xc7, 0x52, 0x9c, 0x01, 0x56, 0x67,
0x79, 0xc9, 0x4c, 0xb1, 0xe8, 0x56, 0xb1, 0xf8, 0x2e, 0xb4, 0x8d, 0x71, 0x26, 0xe7, 0xf5, 0x79,
0x7b, 0x95, 0x80, 0xaa, 0xb2, 0x67, 0x39, 0xe1, 0x94, 0x08, 0xdb, 0xf6, 0x21, 0xcd, 0x93, 0x1f,
0x1b, 0x0a, 0x3a, 0x07, 0x4b, 0x92, 0x65, 0xe1, 0xd3, 0xa2, 0x5d, 0x49, 0x96, 0xdd, 0x47, 0xdf,
0x85, 0x8b, 0x82, 0xe0, 0x98, 0x44, 0x61, 0xd9, 0x5e, 0x44, 0x28, 0xb4, 0xdb, 0x24, 0xf2, 0x1a,
0x3a, 0xcd, 0x9e, 0x91, 0xd8, 0x2d, 0x05, 0x76, 0x2d, 0x5f, 0x65, 0x71, 0x64, 0xc6, 0xf6, 0x99,
0x6d, 0x4d, 0x3d, 0xd9, 0xa3, 0x29, 0xab, 0xdc, 0xf0, 0x09, 0x78, 0xe3, 0x98, 0x0d, 0x71, 0x1c,
0x1e, 0x39, 0x55, 0x3f, 0x21, 0xdc, 0xe0, 0xbc, 0xe1, 0xef, 0xce, 0x1d, 0xa9, 0xdc, 0x13, 0x31,
0x1d, 0x91, 0x28, 0x1c, 0xc6, 0x6c, 0xe8, 0x81, 0x86, 0x2b, 0x18, 0x92, 0xea, 0x57, 0x0a, 0xa6,
0x56, 0x40, 0x85, 0x61, 0xc4, 0xf2, 0x54, 0x6a, 0xf0, 0xb9, 0x41, 0xd7, 0xd0, 0x1f, 0xe5, 0xc9,
0xb6, 0xa2, 0xa2, 0xaf, 0xc0, 0x8a, 0x95, 0x64, 0x7b, 0x7b, 0x82, 0x48, 0x8d, 0x3a, 0x37, 0xe8,
0x18, 0xe2, 0x8f, 0x34, 0xcd, 0xff, 0xbd, 0x0b, 0xab, 0x81, 0x8a, 0x2e, 0x39, 0x20, 0xff, 0x4f,
0x7d, 0xe5, 0xb8, 0xfa, 0x5e, 0x7e, 0xa5, 0xfa, 0x6e, 0x9c, 0xba, 0xbe, 0x9b, 0xaf, 0x54, 0xdf,
0xad, 0x57, 0xab, 0x6f, 0x58, 0x5c, 0xdf, 0xfe, 0x9f, 0x66, 0x92, 0xf3, 0x1a, 0x54, 0xe7, 0x55,
0x70, 0x69, 0x64, 0x46, 0xc5, 0xf6, 0x96, 0xb7, 0xf0, 0x6e, 0x1c, 0xf4, 0x45, 0xa0, 0x84, 0xe6,
0xef, 0xd3, 0xa5, 0x57, 0xbe, 0x4f, 0xbf, 0x07, 0x97, 0x8e, 0xd6, 0x2c, 0xb7, 0xe1, 0x88, 0xbc,
0x65, 0x9d, 0xbb, 0x0b, 0xf3, 0x45, 0x5b, 0xc4, 0x2b, 0x42, 0xdf, 0x82, 0xf5, 0x4a, 0xd5, 0x4e,
0x37, 0x36, 0xcc, 0x1b, 0x7e, 0xca, 0x9b, 0x6e, 0x39, 0xa9, 0x6e, 0x9b, 0x27, 0xd5, 0xad, 0xff,
0x77, 0x17, 0x56, 0xfa, 0x24, 0x26, 0x92, 0x7c, 0x39, 0xee, 0x1d, 0x3b, 0xee, 0x7d, 0x13, 0x10,
0x4d, 0xe5, 0xad, 0x0f, 0xc3, 0x8c, 0xd3, 0x04, 0xf3, 0x49, 0xf8, 0x94, 0x4c, 0x8a, 0x86, 0xd8,
0xd3, 0x9c, 0x1d, 0xc3, 0xb8, 0x4f, 0x26, 0xe2, 0xa5, 0xe3, 0x5f, 0x75, 0xde, 0x32, 0x1d, 0xb0,
0x9c, 0xb7, 0xbe, 0x03, 0x9d, 0x99, 0x23, 0x3a, 0x2f, 0x01, 0x6c, 0x3b, 0x9b, 0x9e, 0xeb, 0xff,
0xdb, 0x81, 0xd6, 0x03, 0x86, 0x23, 0xfd, 0xf2, 0x39, 0x63, 0x1a, 0xcb, 0xa1, 0xb6, 0x36, 0x3f,
0xd4, 0x5e, 0x86, 0xe9, 0xe3, 0xc5, 0x26, 0xb2, 0xf2, 0x9a, 0xa9, 0xbc, 0x4a, 0xea, 0xb3, 0xaf,
0x92, 0x77, 0xa1, 0x4d, 0x95, 0x41, 0x61, 0x86, 0xe5, 0xbe, 0xe9, 0x89, 0xad, 0x00, 0x34, 0x69,
0x47, 0x51, 0xd4, 0xb3, 0xa5, 0x10, 0xd0, 0xcf, 0x96, 0xe5, 0x53, 0x3f, 0x5b, 0xac, 0x12, 0xfd,
0x6c, 0xf9, 0xa5, 0x03, 0xa0, 0x1d, 0x57, 0xfd, 0xe0, 0xa8, 0x52, 0xe7, 0x2c, 0x4a, 0x55, 0xb3,
0xd6, 0x99, 0x22, 0x31, 0x96, 0xd3, 0xa2, 0x12, 0x36, 0x38, 0x48, 0x65, 0xcd, 0xb0, 0x6c, 0x41,
0x09, 0xff, 0xb7, 0x0e, 0x80, 0xee, 0x0a, 0xc6, 0x8c, 0x79, 0xf8, 0x39, 0x27, 0x3f, 0xe8, 0x6a,
0xb3, 0xa1, 0xbb, 0x5b, 0x84, 0x4e, 0xf5, 0x36, 0xf5, 0x10, 0x5f, 0xe0, 0x43, 0x65, 0x02, 0x2f,
0x9c, 0xb7, 0xd1, 0xd5, 0xdf, 0xfe, 0xef, 0x1c, 0xe8, 0x58, 0xeb, 0x8c, 0x49, 0x33, 0x59, 0x76,
0xe6, 0xb3, 0xac, 0xc7, 0x98, 0x84, 0xf1, 0x49, 0x28, 0xe8, 0x0b, 0x62, 0x0d, 0x02, 0x43, 0xda,
0xa5, 0x2f, 0xc8, 0x0c, 0x78, 0xdd, 0x59, 0xf0, 0x5e, 0x83, 0x35, 0x4e, 0x46, 0x24, 0x95, 0xf1,
0x24, 0x4c, 0x58, 0x44, 0xf7, 0x28, 0x89, 0x34, 0x1a, 0x9a, 0x41, 0xaf, 0x60, 0x3c, 0xb4, 0x74,
0xff, 0x17, 0x0e, 0xb4, 0x1f, 0x8a, 0xf1, 0x0e, 0x13, 0xba, 0xc8, 0xd0, 0x15, 0xe8, 0xd8, 0xc6,
0x66, 0x2a, 0xdc, 0xd1, 0x08, 0x6b, 0x8f, 0xa6, 0xbf, 0x3a, 0xaa, 0xd6, 0x9e, 0x88, 0xb1, 0x0d,
0x53, 0x27, 0x30, 0x0b, 0x74, 0x11, 0x9a, 0x89, 0x18, 0xeb, 0xa9, 0xdb, 0xc2, 0xb2, 0x5c, 0x2b,
0x5f, 0xa7, 0x97, 0x55, 0x5d, 0x5f, 0x56, 0x53, 0x82, 0xff, 0x67, 0x07, 0x90, 0xfd, 0x55, 0xf3,
0x33, 0xfd, 0x34, 0xad, 0xb3, 0x5c, 0xfd, 0xe5, 0xb4, 0xa6, 0x31, 0x3e, 0x43, 0x9b, 0x6b, 0x0a,
0xee, 0x91, 0xa6, 0x70, 0x0d, 0xd6, 0x22, 0xb2, 0x87, 0xf3, 0xb8, 0x7a, 0xbf, 0x1a, 0x93, 0x7b,
0x96, 0xf1, 0xb8, 0x6a, 0x79, 0x77, 0x9b, 0x93, 0x88, 0xa4, 0x92, 0xe2, 0x58, 0xff, 0xe5, 0x70,
0x11, 0x9a, 0xb9, 0x50, 0x48, 0x28, 0x63, 0x57, 0xae, 0xd1, 0xfb, 0x80, 0x48, 0x3a, 0xe2, 0x93,
0x4c, 0x81, 0x38, 0xc3, 0x42, 0x1c, 0x32, 0x1e, 0xd9, 0x46, 0xbd, 0x56, 0x72, 0x76, 0x2c, 0x43,
0x3d, 0x4f, 0x25, 0x49, 0x71, 0x2a, 0x8b, 0x7e, 0x6d, 0x56, 0x2a, 0xf5, 0x54, 0x84, 0x22, 0xcf,
0x08, 0xb7, 0x69, 0x6d, 0x50, 0xb1, 0xab, 0x96, 0xaa, 0x95, 0x8b, 0x7d, 0xbc, 0xf5, 0xd1, 0xad,
0xa9, 0x7a, 0xd3, 0xa2, 0xbb, 0x86, 0x5c, 0xe8, 0xf6, 0x3f, 0x85, 0xb5, 0x07, 0x54, 0xc8, 0x1d,
0x16, 0xd3, 0xd1, 0xe4, 0xcc, 0x37, 0x8e, 0x1f, 0x03, 0xaa, 0xaa, 0x11, 0x19, 0x4b, 0x67, 0x06,
0x06, 0xe7, 0xf4, 0x03, 0xc3, 0x15, 0xe8, 0x64, 0x5a, 0x8d, 0xfe, 0x1b, 0xad, 0x48, 0x5e, 0xdb,
0xd0, 0x54, 0x68, 0xc5, 0xd5, 0x4f, 0xa0, 0x55, 0xfe, 0x01, 0x87, 0x7a, 0xd0, 0x19, 0xa4, 0x54,
0xea, 0x29, 0x8d, 0xa6, 0xe3, 0xde, 0x1b, 0xa8, 0x0d, 0x8d, 0x1f, 0x12, 0x1c, 0xcb, 0xfd, 0x49,
0xcf, 0x41, 0x1d, 0x68, 0xde, 0x19, 0xa6, 0x8c, 0x27, 0x38, 0xee, 0xd5, 0xae, 0x6e, 0xc1, 0xda,
0x91, 0x97, 0xb1, 0x12, 0x09, 0xd8, 0xa1, 0xf2, 0x26, 0xea, 0xbd, 0x81, 0x56, 0xa1, 0xbd, 0xcd,
0xe2, 0x3c, 0x49, 0x0d, 0xc1, 0xb9, 0xfb, 0xf1, 0xcf, 0x3e, 0x1a, 0x53, 0xb9, 0x9f, 0x0f, 0x95,
0xc1, 0x37, 0x8c, 0x07, 0xef, 0x53, 0x66, 0xbf, 0x6e, 0x14, 0x05, 0x7f, 0x43, 0x3b, 0x55, 0x2e,
0xb3, 0xe1, 0x70, 0x59, 0x53, 0x3e, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x7b, 0xa3,
0xc9, 0xda, 0x1c, 0x00, 0x00,
0x15, 0xdf, 0xd1, 0xc8, 0x96, 0xf4, 0x24, 0xcb, 0x72, 0xc7, 0xc9, 0x2a, 0x1f, 0xbb, 0xeb, 0x0c,
0x0b, 0x98, 0x84, 0x4d, 0x82, 0x77, 0x37, 0xd9, 0x02, 0x8a, 0x90, 0x58, 0x4b, 0x70, 0xe5, 0x03,
0x33, 0x0e, 0xa9, 0x82, 0xcb, 0x54, 0x4b, 0xd3, 0x96, 0x9b, 0xcc, 0x4c, 0x8f, 0xbb, 0x7b, 0xec,
0x28, 0x27, 0x0e, 0x9c, 0xa0, 0xe0, 0xc6, 0x85, 0x2a, 0x38, 0x73, 0xe1, 0xbc, 0x37, 0xa8, 0xe2,
0xc4, 0x89, 0x13, 0x17, 0xfe, 0x15, 0x8a, 0x03, 0xd5, 0x1f, 0x33, 0x1a, 0xc9, 0xb2, 0x23, 0x7b,
0x6b, 0x77, 0xb3, 0x55, 0x7b, 0x9b, 0x7e, 0xef, 0x75, 0xcf, 0xfb, 0xf8, 0xbd, 0xd7, 0xef, 0xcd,
0x40, 0x9b, 0x26, 0x92, 0xf0, 0x04, 0x47, 0x37, 0x52, 0xce, 0x24, 0x43, 0xe7, 0x63, 0x1a, 0x1d,
0x64, 0xc2, 0xac, 0x6e, 0xe4, 0xcc, 0x4b, 0xad, 0x01, 0x8b, 0x63, 0x96, 0x18, 0xf2, 0xa5, 0x96,
0x18, 0xec, 0x91, 0x18, 0x9b, 0x95, 0xf7, 0x37, 0x07, 0x96, 0x36, 0x59, 0x9c, 0xb2, 0x84, 0x24,
0x72, 0x2b, 0xd9, 0x65, 0xe8, 0x02, 0x2c, 0x26, 0x2c, 0x24, 0x5b, 0xbd, 0xae, 0xb3, 0xe6, 0xac,
0xbb, 0xbe, 0x5d, 0x21, 0x04, 0x55, 0xce, 0x22, 0xd2, 0xad, 0xac, 0x39, 0xeb, 0x0d, 0x5f, 0x3f,
0xa3, 0xbb, 0x00, 0x42, 0x62, 0x49, 0x82, 0x01, 0x0b, 0x49, 0xd7, 0x5d, 0x73, 0xd6, 0xdb, 0x1b,
0x6b, 0x37, 0x66, 0x6a, 0x71, 0x63, 0x47, 0x09, 0x6e, 0xb2, 0x90, 0xf8, 0x0d, 0x91, 0x3f, 0xa2,
0x1f, 0x02, 0x90, 0x17, 0x92, 0xe3, 0x80, 0x26, 0xbb, 0xac, 0x5b, 0x5d, 0x73, 0xd7, 0x9b, 0x1b,
0x57, 0x27, 0x0f, 0xb0, 0xca, 0x3f, 0x24, 0xa3, 0x67, 0x38, 0xca, 0xc8, 0x36, 0xa6, 0xdc, 0x6f,
0xe8, 0x4d, 0x4a, 0x5d, 0xef, 0x3f, 0x0e, 0x2c, 0x17, 0x06, 0xe8, 0x77, 0x08, 0xf4, 0x5d, 0x58,
0xd0, 0xaf, 0xd0, 0x16, 0x34, 0x37, 0xde, 0x3d, 0x46, 0xa3, 0x09, 0xbb, 0x7d, 0xb3, 0x05, 0xfd,
0x0c, 0xce, 0x89, 0xac, 0x3f, 0xc8, 0x59, 0x81, 0xa6, 0x8a, 0x6e, 0x45, 0xab, 0x36, 0xdf, 0x49,
0xa8, 0x7c, 0x80, 0x55, 0xe9, 0x7d, 0x58, 0x54, 0x27, 0x65, 0x42, 0x7b, 0xa9, 0xb9, 0x71, 0x79,
0xa6, 0x91, 0x3b, 0x5a, 0xc4, 0xb7, 0xa2, 0xde, 0x65, 0xb8, 0xf8, 0x80, 0xc8, 0x29, 0xeb, 0x7c,
0xb2, 0x9f, 0x11, 0x21, 0x2d, 0xf3, 0x29, 0x8d, 0xc9, 0x53, 0x3a, 0x78, 0xbe, 0xb9, 0x87, 0x93,
0x84, 0x44, 0x39, 0xf3, 0x2d, 0xb8, 0xfc, 0x80, 0xe8, 0x0d, 0x54, 0x48, 0x3a, 0x10, 0x53, 0xec,
0xf3, 0x70, 0xee, 0x01, 0x91, 0xbd, 0x70, 0x8a, 0xfc, 0x0c, 0xea, 0x4f, 0x54, 0xb0, 0x15, 0x0c,
0x6e, 0x43, 0x0d, 0x87, 0x21, 0x27, 0x42, 0x58, 0x2f, 0x5e, 0x99, 0xa9, 0xf1, 0x3d, 0x23, 0xe3,
0xe7, 0xc2, 0xb3, 0x60, 0xe2, 0xfd, 0x12, 0x60, 0x2b, 0xa1, 0x72, 0x1b, 0x73, 0x1c, 0x8b, 0x63,
0x01, 0xd6, 0x83, 0x96, 0x90, 0x98, 0xcb, 0x20, 0xd5, 0x72, 0xd6, 0xe5, 0x73, 0xa0, 0xa1, 0xa9,
0xb7, 0x99, 0xd3, 0xbd, 0x9f, 0x03, 0xec, 0x48, 0x4e, 0x93, 0xe1, 0x23, 0x2a, 0xa4, 0x7a, 0xd7,
0x81, 0x92, 0x53, 0x46, 0xb8, 0xeb, 0x0d, 0xdf, 0xae, 0x4a, 0xe1, 0xa8, 0xcc, 0x1f, 0x8e, 0xbb,
0xd0, 0xcc, 0xdd, 0xfd, 0x58, 0x0c, 0xd1, 0x2d, 0xa8, 0xf6, 0xb1, 0x20, 0x27, 0xba, 0xe7, 0xb1,
0x18, 0xde, 0xc7, 0x82, 0xf8, 0x5a, 0xd2, 0xfb, 0x6b, 0x05, 0x56, 0x27, 0xc2, 0x62, 0x1d, 0x7f,
0xfa, 0xa3, 0x94, 0x9b, 0xc3, 0xfe, 0x56, 0x4f, 0xab, 0xef, 0xfa, 0xfa, 0x19, 0x79, 0xd0, 0x1a,
0xb0, 0x28, 0x22, 0x03, 0x49, 0x59, 0xb2, 0xd5, 0xd3, 0x48, 0x73, 0xfd, 0x09, 0x9a, 0x92, 0x49,
0x31, 0x97, 0xd4, 0x2c, 0x85, 0x4e, 0x39, 0xd7, 0x9f, 0xa0, 0xa1, 0x6f, 0x41, 0x47, 0x72, 0x7c,
0x40, 0xa2, 0x40, 0xd2, 0x98, 0x08, 0x89, 0xe3, 0xb4, 0xbb, 0xb0, 0xe6, 0xac, 0x57, 0xfd, 0x65,
0x43, 0x7f, 0x9a, 0x93, 0xd1, 0x4d, 0x38, 0x37, 0xcc, 0x30, 0xc7, 0x89, 0x24, 0xa4, 0x24, 0xbd,
0xa8, 0xa5, 0x51, 0xc1, 0x1a, 0x6f, 0xb8, 0x0e, 0x2b, 0x4a, 0x8c, 0x65, 0xb2, 0x24, 0x5e, 0xd3,
0xe2, 0x1d, 0xcb, 0x28, 0x84, 0xbd, 0x4f, 0x1c, 0x38, 0x3f, 0xe5, 0x2f, 0x91, 0xb2, 0x44, 0x90,
0x33, 0x38, 0xec, 0x2c, 0x11, 0x47, 0x77, 0x4c, 0x21, 0x51, 0x49, 0x3b, 0x27, 0x16, 0x8d, 0xbc,
0xf7, 0x1b, 0x17, 0xde, 0xdc, 0xe4, 0x44, 0x97, 0xb9, 0xdc, 0xfb, 0x67, 0x0f, 0xf6, 0x9b, 0x50,
0x0b, 0xfb, 0x41, 0x82, 0xe3, 0x3c, 0xad, 0x16, 0xc3, 0xfe, 0x13, 0x1c, 0x13, 0xf4, 0x0d, 0x68,
0x8f, 0xa3, 0xab, 0x28, 0x3a, 0xe6, 0x0d, 0x7f, 0x8a, 0x8a, 0xde, 0x85, 0xa5, 0x22, 0xc2, 0x5a,
0xac, 0xaa, 0xc5, 0x26, 0x89, 0x05, 0xa6, 0x16, 0x4e, 0xc0, 0xd4, 0xe2, 0x0c, 0x4c, 0xad, 0x41,
0xb3, 0x84, 0x1f, 0x1d, 0x4d, 0xd7, 0x2f, 0x93, 0x54, 0x1a, 0x9a, 0x5b, 0xa7, 0x5b, 0x5f, 0x73,
0xd6, 0x5b, 0xbe, 0x5d, 0xa1, 0x5b, 0x70, 0xee, 0x80, 0x72, 0x99, 0xe1, 0xc8, 0x56, 0x22, 0xa5,
0x87, 0xe8, 0x36, 0x74, 0xae, 0xce, 0x62, 0xa1, 0x0d, 0x58, 0x4d, 0xf7, 0x46, 0x82, 0x0e, 0xa6,
0xb6, 0x80, 0xde, 0x32, 0x93, 0xe7, 0xfd, 0xc3, 0x81, 0xf3, 0x3d, 0xce, 0xd2, 0xd7, 0x22, 0x14,
0xb9, 0x93, 0xab, 0x27, 0x38, 0x79, 0xe1, 0xa8, 0x93, 0xbd, 0xdf, 0x55, 0xe0, 0x82, 0x41, 0xd4,
0x76, 0xee, 0xd8, 0xcf, 0xc0, 0x8a, 0x6f, 0xc2, 0xf2, 0xf8, 0xad, 0x46, 0x60, 0xb6, 0x19, 0x5f,
0x87, 0x76, 0x11, 0x60, 0x23, 0xf7, 0xf9, 0x42, 0xca, 0xfb, 0x6d, 0x05, 0x56, 0x55, 0x50, 0xbf,
0xf2, 0x86, 0xf2, 0xc6, 0x9f, 0x1d, 0x40, 0x06, 0x1d, 0xf7, 0x22, 0x8a, 0xc5, 0x17, 0xe9, 0x8b,
0x55, 0x58, 0xc0, 0x4a, 0x07, 0xeb, 0x02, 0xb3, 0xf0, 0x04, 0x74, 0x54, 0xb4, 0x3e, 0x2b, 0xed,
0x8a, 0x97, 0xba, 0xe5, 0x97, 0xfe, 0xc9, 0x81, 0x95, 0x7b, 0x91, 0x24, 0xfc, 0x35, 0x75, 0xca,
0xdf, 0x2b, 0x79, 0xd4, 0xb6, 0x92, 0x90, 0xbc, 0xf8, 0x22, 0x15, 0x7c, 0x0b, 0x60, 0x97, 0x92,
0x28, 0x2c, 0xa3, 0xb7, 0xa1, 0x29, 0x9f, 0x0a, 0xb9, 0x5d, 0xa8, 0xe9, 0x43, 0x0a, 0xd4, 0xe6,
0x4b, 0xd5, 0xed, 0x99, 0xce, 0xdf, 0x76, 0x7b, 0xf5, 0xb9, 0xbb, 0x3d, 0xbd, 0xcd, 0x76, 0x7b,
0xff, 0xaa, 0xc2, 0xd2, 0x56, 0x22, 0x08, 0x97, 0x67, 0x77, 0xde, 0x15, 0x68, 0x88, 0x3d, 0xcc,
0xb5, 0xa1, 0xd6, 0x7d, 0x63, 0x42, 0xd9, 0xb5, 0xee, 0xab, 0x5c, 0x5b, 0x9d, 0xb3, 0x38, 0x2c,
0x9c, 0x54, 0x1c, 0x16, 0x4f, 0x70, 0x71, 0xed, 0xd5, 0xc5, 0xa1, 0x7e, 0xf4, 0xf6, 0x55, 0x06,
0x92, 0x61, 0xac, 0xc6, 0x93, 0x5e, 0xb7, 0xa1, 0xf9, 0x63, 0x02, 0x7a, 0x1b, 0xa0, 0xe8, 0xc4,
0xcc, 0x3d, 0x5a, 0xf5, 0x4b, 0x14, 0x75, 0x77, 0x73, 0x76, 0xa8, 0x7a, 0xc5, 0xa6, 0xee, 0x15,
0xed, 0x0a, 0x7d, 0x00, 0x75, 0xce, 0x0e, 0x83, 0x10, 0x4b, 0xdc, 0x6d, 0xe9, 0xe0, 0x5d, 0x9c,
0xe9, 0xec, 0xfb, 0x11, 0xeb, 0xfb, 0x35, 0xce, 0x0e, 0x7b, 0x58, 0x62, 0x74, 0x17, 0x9a, 0x1a,
0x01, 0xc2, 0x6c, 0x5c, 0xd2, 0x1b, 0xdf, 0x9e, 0xdc, 0x68, 0x07, 0xd4, 0x1f, 0x29, 0x39, 0xb5,
0xc9, 0x37, 0xd0, 0x14, 0xfa, 0x80, 0x8b, 0x50, 0x4f, 0xb2, 0x38, 0xe0, 0xec, 0x50, 0x74, 0xdb,
0xba, 0x6f, 0xac, 0x25, 0x59, 0xec, 0xb3, 0x43, 0x81, 0xee, 0x43, 0xed, 0x80, 0x70, 0x41, 0x59,
0xd2, 0x5d, 0xd6, 0xa3, 0xe8, 0xfa, 0x31, 0xe3, 0x9a, 0x41, 0x8c, 0x3a, 0xee, 0x99, 0x91, 0xf7,
0xf3, 0x8d, 0xde, 0xbf, 0xab, 0xb0, 0xb4, 0x43, 0x30, 0x1f, 0xec, 0x9d, 0x1d, 0x50, 0xab, 0xb0,
0xc0, 0xc9, 0x7e, 0xd1, 0x9c, 0x9b, 0x45, 0x11, 0x5f, 0xf7, 0x84, 0xf8, 0x56, 0xe7, 0xe8, 0xd8,
0x17, 0x66, 0x74, 0xec, 0x1d, 0x70, 0x43, 0x11, 0x69, 0xe8, 0x34, 0x7c, 0xf5, 0xa8, 0xfa, 0xec,
0x34, 0xc2, 0x03, 0xb2, 0xc7, 0xa2, 0x90, 0xf0, 0x60, 0xc8, 0x59, 0x66, 0xfa, 0xec, 0x96, 0xdf,
0x29, 0x31, 0x1e, 0x28, 0x3a, 0xba, 0x03, 0xf5, 0x50, 0x44, 0x81, 0x1c, 0xa5, 0x44, 0xe3, 0xa7,
0x7d, 0x8c, 0x99, 0x3d, 0x11, 0x3d, 0x1d, 0xa5, 0xc4, 0xaf, 0x85, 0xe6, 0x01, 0xdd, 0x82, 0x55,
0x41, 0x38, 0xc5, 0x11, 0x7d, 0x49, 0xc2, 0x80, 0xbc, 0x48, 0x79, 0x90, 0x46, 0x38, 0xd1, 0x20,
0x6b, 0xf9, 0x68, 0xcc, 0xfb, 0xf8, 0x45, 0xca, 0xb7, 0x23, 0x9c, 0xa0, 0x75, 0xe8, 0xb0, 0x4c,
0xa6, 0x99, 0x0c, 0x2c, 0x0c, 0x68, 0xa8, 0x31, 0xe7, 0xfa, 0x6d, 0x43, 0xd7, 0x51, 0x17, 0x5b,
0xe1, 0xcc, 0x29, 0xa4, 0x79, 0xaa, 0x29, 0xa4, 0x75, 0xba, 0x29, 0x64, 0x69, 0xf6, 0x14, 0x82,
0xda, 0x50, 0x49, 0xf6, 0x35, 0xd6, 0x5c, 0xbf, 0x92, 0xec, 0xab, 0x40, 0x4a, 0x96, 0x3e, 0xd7,
0x18, 0x73, 0x7d, 0xfd, 0xac, 0x92, 0x28, 0x26, 0x92, 0xd3, 0x81, 0x72, 0x4b, 0xb7, 0xa3, 0xe3,
0x50, 0xa2, 0x78, 0xff, 0x73, 0xc7, 0xb0, 0x12, 0x59, 0x24, 0xc5, 0xe7, 0x35, 0xc1, 0x14, 0x58,
0x74, 0xcb, 0x58, 0x7c, 0x07, 0x9a, 0x46, 0x39, 0x13, 0xf3, 0xea, 0xb4, 0xbe, 0x4a, 0x40, 0x65,
0xd9, 0x7e, 0x46, 0x38, 0x25, 0xc2, 0x96, 0x7d, 0x48, 0xb2, 0xf8, 0xa7, 0x86, 0x82, 0xce, 0xc1,
0x82, 0x64, 0x69, 0xf0, 0x3c, 0x2f, 0x57, 0x92, 0xa5, 0x0f, 0xd1, 0xf7, 0xe1, 0x92, 0x20, 0x38,
0x22, 0x61, 0x50, 0x94, 0x17, 0x11, 0x08, 0x6d, 0x36, 0x09, 0xbb, 0x35, 0x1d, 0xe6, 0xae, 0x91,
0xd8, 0x29, 0x04, 0x76, 0x2c, 0x5f, 0x45, 0x71, 0x60, 0xda, 0xf6, 0x89, 0x6d, 0x75, 0xdd, 0xd9,
0xa3, 0x31, 0xab, 0xd8, 0xf0, 0x11, 0x74, 0x87, 0x11, 0xeb, 0xe3, 0x28, 0x38, 0xf2, 0x56, 0x3d,
0x42, 0xb8, 0xfe, 0x05, 0xc3, 0xdf, 0x99, 0x7a, 0xa5, 0x32, 0x4f, 0x44, 0x74, 0x40, 0xc2, 0xa0,
0x1f, 0xb1, 0x7e, 0x17, 0x34, 0x5c, 0xc1, 0x90, 0x54, 0xbd, 0x52, 0x30, 0xb5, 0x02, 0xca, 0x0d,
0x03, 0x96, 0x25, 0x52, 0x83, 0xcf, 0xf5, 0xdb, 0x86, 0xfe, 0x24, 0x8b, 0x37, 0x15, 0x15, 0x7d,
0x0d, 0x96, 0xac, 0x24, 0xdb, 0xdd, 0x15, 0x44, 0x6a, 0xd4, 0xb9, 0x7e, 0xcb, 0x10, 0x7f, 0xa2,
0x69, 0xde, 0x1f, 0x5d, 0x58, 0xf6, 0x95, 0x77, 0xc9, 0x01, 0xf9, 0x32, 0xd5, 0x95, 0xe3, 0xf2,
0x7b, 0xf1, 0x54, 0xf9, 0x5d, 0x9b, 0x3b, 0xbf, 0xeb, 0xa7, 0xca, 0xef, 0xc6, 0xe9, 0xf2, 0x1b,
0x8e, 0xf9, 0xca, 0xf0, 0x97, 0x89, 0xe0, 0xbc, 0x06, 0xd9, 0x79, 0x0d, 0x5c, 0x1a, 0x9a, 0x56,
0xb1, 0xb9, 0xd1, 0x9d, 0x79, 0x37, 0x6e, 0xf5, 0x84, 0xaf, 0x84, 0xa6, 0xef, 0xd3, 0x85, 0x53,
0xdf, 0xa7, 0x3f, 0x80, 0xcb, 0x47, 0x73, 0x96, 0x5b, 0x77, 0x84, 0xdd, 0x45, 0x1d, 0xbb, 0x8b,
0xd3, 0x49, 0x9b, 0xfb, 0x2b, 0x44, 0xdf, 0x81, 0xd5, 0x52, 0xd6, 0x8e, 0x37, 0xd6, 0xcc, 0x0c,
0x3f, 0xe6, 0x8d, 0xb7, 0x9c, 0x94, 0xb7, 0xf5, 0x93, 0xf2, 0xd6, 0xfb, 0xa7, 0x0b, 0x4b, 0x3d,
0x12, 0x11, 0x49, 0xbe, 0x6a, 0xf7, 0x8e, 0x6d, 0xf7, 0xbe, 0x0d, 0x88, 0x26, 0xf2, 0xf6, 0x07,
0x41, 0xca, 0x69, 0x8c, 0xf9, 0x28, 0x78, 0x4e, 0x46, 0x79, 0x41, 0xec, 0x68, 0xce, 0xb6, 0x61,
0x3c, 0x24, 0x23, 0xf1, 0xca, 0xf6, 0xaf, 0xdc, 0x6f, 0x99, 0x0a, 0x58, 0xf4, 0x5b, 0xdf, 0x83,
0xd6, 0xc4, 0x2b, 0x5a, 0xaf, 0x00, 0x6c, 0x33, 0x1d, 0xbf, 0xd7, 0xfb, 0xaf, 0x03, 0x8d, 0x47,
0x0c, 0x87, 0x7a, 0xf2, 0x39, 0x63, 0x18, 0x8b, 0xa6, 0xb6, 0x32, 0xdd, 0xd4, 0x5e, 0x81, 0xf1,
0xf0, 0x62, 0x03, 0x59, 0x9a, 0x66, 0x4a, 0x53, 0x49, 0x75, 0x72, 0x2a, 0x79, 0x07, 0x9a, 0x54,
0x29, 0x14, 0xa4, 0x58, 0xee, 0x99, 0x9a, 0xd8, 0xf0, 0x41, 0x93, 0xb6, 0x15, 0x45, 0x8d, 0x2d,
0xb9, 0x80, 0x1e, 0x5b, 0x16, 0xe7, 0x1e, 0x5b, 0xec, 0x21, 0x7a, 0x6c, 0xf9, 0xb5, 0x03, 0xa0,
0x0d, 0x57, 0xf5, 0xe0, 0xe8, 0xa1, 0xce, 0x59, 0x0e, 0x55, 0xc5, 0x5a, 0x47, 0x8a, 0x44, 0x58,
0x8e, 0x93, 0x4a, 0x58, 0xe7, 0x20, 0x15, 0x35, 0xc3, 0xb2, 0x09, 0x25, 0xbc, 0xdf, 0x3b, 0x00,
0xba, 0x2a, 0x18, 0x35, 0xa6, 0xe1, 0xe7, 0x9c, 0x3c, 0xd0, 0x55, 0x26, 0x5d, 0x77, 0x3f, 0x77,
0xdd, 0x09, 0x5f, 0x4c, 0x4b, 0x1d, 0x78, 0x6e, 0xbc, 0xf5, 0xae, 0x7e, 0xf6, 0xfe, 0xe0, 0x40,
0xcb, 0x6a, 0x67, 0x54, 0x9a, 0x88, 0xb2, 0x33, 0x1d, 0x65, 0xdd, 0xc6, 0xc4, 0x8c, 0x8f, 0x02,
0x41, 0x5f, 0x12, 0xab, 0x10, 0x18, 0xd2, 0x0e, 0x7d, 0x49, 0x26, 0xc0, 0xeb, 0x4e, 0x82, 0xf7,
0x3a, 0xac, 0x70, 0x32, 0x20, 0x89, 0x8c, 0x46, 0x41, 0xcc, 0x42, 0xba, 0x4b, 0x49, 0xa8, 0xd1,
0x50, 0xf7, 0x3b, 0x39, 0xe3, 0xb1, 0xa5, 0x7b, 0xbf, 0x72, 0xa0, 0xf9, 0x58, 0x0c, 0xb7, 0x99,
0xd0, 0x49, 0x86, 0xae, 0x42, 0xcb, 0x16, 0x36, 0x93, 0xe1, 0x8e, 0x46, 0x58, 0x73, 0x30, 0xfe,
0xea, 0xa8, 0x4a, 0x7b, 0x2c, 0x86, 0xd6, 0x4d, 0x2d, 0xdf, 0x2c, 0xd0, 0x25, 0xa8, 0xc7, 0x62,
0xa8, 0xbb, 0x6e, 0x0b, 0xcb, 0x62, 0xad, 0x6c, 0x1d, 0x5f, 0x56, 0x55, 0x7d, 0x59, 0x8d, 0x09,
0xde, 0x27, 0x0e, 0x20, 0xfb, 0x55, 0xf3, 0x53, 0xfd, 0x84, 0xd0, 0x51, 0x2e, 0x7f, 0x39, 0xad,
0x68, 0x8c, 0x4f, 0xd0, 0xa6, 0x8a, 0x82, 0x7b, 0xa4, 0x28, 0x5c, 0x87, 0x95, 0x90, 0xec, 0xe2,
0x2c, 0x2a, 0xdf, 0xaf, 0x46, 0xe5, 0x8e, 0x65, 0x4c, 0x7c, 0xc5, 0x6f, 0x6f, 0x72, 0x12, 0x92,
0x44, 0x52, 0x1c, 0xe9, 0x9f, 0x4b, 0x97, 0xa0, 0x9e, 0x09, 0x85, 0x84, 0xc2, 0x77, 0xc5, 0x1a,
0xbd, 0x07, 0x88, 0x24, 0x03, 0x3e, 0x4a, 0x15, 0x88, 0x53, 0x2c, 0xc4, 0x21, 0xe3, 0xa1, 0x2d,
0xd4, 0x2b, 0x05, 0x67, 0xdb, 0x32, 0xd4, 0x78, 0x2a, 0x49, 0x82, 0x13, 0x99, 0xd7, 0x6b, 0xb3,
0x52, 0xa1, 0xa7, 0x22, 0x10, 0x59, 0x4a, 0xb8, 0x0d, 0x6b, 0x8d, 0x8a, 0x1d, 0xb5, 0x54, 0xa5,
0x5c, 0xec, 0xe1, 0x8d, 0x0f, 0x6f, 0x8f, 0x8f, 0x37, 0x25, 0xba, 0x6d, 0xc8, 0xf9, 0xd9, 0xde,
0xc7, 0xb0, 0xf2, 0x88, 0x0a, 0xb9, 0xcd, 0x22, 0x3a, 0x18, 0x9d, 0xf9, 0xc6, 0xf1, 0x22, 0x40,
0xe5, 0x63, 0xec, 0x2f, 0x8c, 0x71, 0xc3, 0xe0, 0xcc, 0xdf, 0x30, 0x5c, 0x85, 0x56, 0xaa, 0x8f,
0xd1, 0x3f, 0x4c, 0xf3, 0xe0, 0x35, 0x0d, 0x4d, 0xb9, 0x56, 0x5c, 0xfb, 0x08, 0x1a, 0xc5, 0xaf,
0x56, 0xd4, 0x81, 0xd6, 0x56, 0x42, 0xa5, 0xee, 0xd2, 0x68, 0x32, 0xec, 0xbc, 0x81, 0x9a, 0x50,
0xfb, 0x31, 0xc1, 0x91, 0xdc, 0x1b, 0x75, 0x1c, 0xd4, 0x82, 0xfa, 0xbd, 0x7e, 0xc2, 0x78, 0x8c,
0xa3, 0x4e, 0xe5, 0xda, 0x06, 0xac, 0x1c, 0x99, 0x8c, 0x95, 0x88, 0xcf, 0x0e, 0x95, 0x35, 0x61,
0xe7, 0x0d, 0xb4, 0x0c, 0xcd, 0x4d, 0x16, 0x65, 0x71, 0x62, 0x08, 0xce, 0xfd, 0x3b, 0xbf, 0xf8,
0x70, 0x48, 0xe5, 0x5e, 0xd6, 0x57, 0x0a, 0xdf, 0x34, 0x16, 0xbc, 0x47, 0x99, 0x7d, 0xba, 0x99,
0x27, 0xfc, 0x4d, 0x6d, 0x54, 0xb1, 0x4c, 0xfb, 0xfd, 0x45, 0x4d, 0x79, 0xff, 0xff, 0x01, 0x00,
0x00, 0xff, 0xff, 0xf3, 0x90, 0xe6, 0x06, 0xc4, 0x1e, 0x00, 0x00,
}

View File

@ -264,6 +264,39 @@ message ReleaseCollectionRequest {
string collection_name = 3;
}
/**
* Get statistics like row_count.
* WARNING: This API is experimental and not useful for now.
*/
message GetStatisticsRequest {
option (common.privilege_ext_obj) = {
resource_type: Collection
resource_privilege: PrivilegeRead
resource_name_index: 3
};
// Not useful for now
common.MsgBase base = 1;
// Not useful for now
string db_name = 2;
// The collection name you want get statistics
string collection_name = 3;
// The partition names you want get statistics, empty for all partitions
repeated string partition_names = 4;
// Not useful for now, reserved for future
uint64 guarantee_timestamp = 5;
}
/**
* Will return statistics in stats field like [{key:"row_count",value:"1"}]
* WARNING: This API is experimental and not useful for now.
*/
message GetStatisticsResponse {
// Contain error_code and reason
common.Status status = 1;
// Collection statistics data
repeated common.KeyValuePair stats = 2;
}
/**
* Get collection statistics like row_count.
*/
@ -295,7 +328,7 @@ message GetCollectionStatisticsResponse {
* This is for ShowCollectionsRequest type field.
*/
enum ShowType {
// Will return all colloections
// Will return all collections
All = 0;
// Will return loaded collections with their inMemory_percentages
InMemory = 1;

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,7 @@ service QueryNode {
rpc GetSegmentInfo(GetSegmentInfoRequest) returns (GetSegmentInfoResponse) {}
rpc SyncReplicaSegments(SyncReplicaSegmentsRequest) returns (common.Status) {}
rpc GetStatistics(GetStatisticsRequest) returns (internal.GetStatisticsResponse) {}
rpc Search(SearchRequest) returns (internal.SearchResults) {}
rpc Query(QueryRequest) returns (internal.RetrieveResults) {}
@ -99,6 +100,14 @@ message ReleaseCollectionRequest {
int64 nodeID = 4;
}
message GetStatisticsRequest {
internal.GetStatisticsRequest req = 1;
repeated string dml_channels = 2;
repeated int64 segmentIDs = 3;
bool from_shard_leader = 4;
DataScope scope = 5; // All, Streaming, Historical
}
message LoadPartitionsRequest {
common.MsgBase base = 1;
int64 dbID = 2;

View File

@ -534,6 +534,77 @@ func (m *ReleaseCollectionRequest) GetNodeID() int64 {
return 0
}
type GetStatisticsRequest struct {
Req *internalpb.GetStatisticsRequest `protobuf:"bytes,1,opt,name=req,proto3" json:"req,omitempty"`
DmlChannels []string `protobuf:"bytes,2,rep,name=dml_channels,json=dmlChannels,proto3" json:"dml_channels,omitempty"`
SegmentIDs []int64 `protobuf:"varint,3,rep,packed,name=segmentIDs,proto3" json:"segmentIDs,omitempty"`
FromShardLeader bool `protobuf:"varint,4,opt,name=from_shard_leader,json=fromShardLeader,proto3" json:"from_shard_leader,omitempty"`
Scope DataScope `protobuf:"varint,5,opt,name=scope,proto3,enum=milvus.proto.query.DataScope" json:"scope,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetStatisticsRequest) Reset() { *m = GetStatisticsRequest{} }
func (m *GetStatisticsRequest) String() string { return proto.CompactTextString(m) }
func (*GetStatisticsRequest) ProtoMessage() {}
func (*GetStatisticsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{6}
}
func (m *GetStatisticsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetStatisticsRequest.Unmarshal(m, b)
}
func (m *GetStatisticsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetStatisticsRequest.Marshal(b, m, deterministic)
}
func (m *GetStatisticsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetStatisticsRequest.Merge(m, src)
}
func (m *GetStatisticsRequest) XXX_Size() int {
return xxx_messageInfo_GetStatisticsRequest.Size(m)
}
func (m *GetStatisticsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetStatisticsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetStatisticsRequest proto.InternalMessageInfo
func (m *GetStatisticsRequest) GetReq() *internalpb.GetStatisticsRequest {
if m != nil {
return m.Req
}
return nil
}
func (m *GetStatisticsRequest) GetDmlChannels() []string {
if m != nil {
return m.DmlChannels
}
return nil
}
func (m *GetStatisticsRequest) GetSegmentIDs() []int64 {
if m != nil {
return m.SegmentIDs
}
return nil
}
func (m *GetStatisticsRequest) GetFromShardLeader() bool {
if m != nil {
return m.FromShardLeader
}
return false
}
func (m *GetStatisticsRequest) GetScope() DataScope {
if m != nil {
return m.Scope
}
return DataScope_UnKnown
}
type LoadPartitionsRequest struct {
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
DbID int64 `protobuf:"varint,2,opt,name=dbID,proto3" json:"dbID,omitempty"`
@ -550,7 +621,7 @@ func (m *LoadPartitionsRequest) Reset() { *m = LoadPartitionsRequest{} }
func (m *LoadPartitionsRequest) String() string { return proto.CompactTextString(m) }
func (*LoadPartitionsRequest) ProtoMessage() {}
func (*LoadPartitionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{6}
return fileDescriptor_aab7cc9a69ed26e8, []int{7}
}
func (m *LoadPartitionsRequest) XXX_Unmarshal(b []byte) error {
@ -628,7 +699,7 @@ func (m *ReleasePartitionsRequest) Reset() { *m = ReleasePartitionsReque
func (m *ReleasePartitionsRequest) String() string { return proto.CompactTextString(m) }
func (*ReleasePartitionsRequest) ProtoMessage() {}
func (*ReleasePartitionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{7}
return fileDescriptor_aab7cc9a69ed26e8, []int{8}
}
func (m *ReleasePartitionsRequest) XXX_Unmarshal(b []byte) error {
@ -698,7 +769,7 @@ func (m *GetPartitionStatesRequest) Reset() { *m = GetPartitionStatesReq
func (m *GetPartitionStatesRequest) String() string { return proto.CompactTextString(m) }
func (*GetPartitionStatesRequest) ProtoMessage() {}
func (*GetPartitionStatesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{8}
return fileDescriptor_aab7cc9a69ed26e8, []int{9}
}
func (m *GetPartitionStatesRequest) XXX_Unmarshal(b []byte) error {
@ -759,7 +830,7 @@ func (m *GetPartitionStatesResponse) Reset() { *m = GetPartitionStatesRe
func (m *GetPartitionStatesResponse) String() string { return proto.CompactTextString(m) }
func (*GetPartitionStatesResponse) ProtoMessage() {}
func (*GetPartitionStatesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{9}
return fileDescriptor_aab7cc9a69ed26e8, []int{10}
}
func (m *GetPartitionStatesResponse) XXX_Unmarshal(b []byte) error {
@ -807,7 +878,7 @@ func (m *GetSegmentInfoRequest) Reset() { *m = GetSegmentInfoRequest{} }
func (m *GetSegmentInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetSegmentInfoRequest) ProtoMessage() {}
func (*GetSegmentInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{10}
return fileDescriptor_aab7cc9a69ed26e8, []int{11}
}
func (m *GetSegmentInfoRequest) XXX_Unmarshal(b []byte) error {
@ -861,7 +932,7 @@ func (m *GetSegmentInfoResponse) Reset() { *m = GetSegmentInfoResponse{}
func (m *GetSegmentInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetSegmentInfoResponse) ProtoMessage() {}
func (*GetSegmentInfoResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{11}
return fileDescriptor_aab7cc9a69ed26e8, []int{12}
}
func (m *GetSegmentInfoResponse) XXX_Unmarshal(b []byte) error {
@ -908,7 +979,7 @@ func (m *GetShardLeadersRequest) Reset() { *m = GetShardLeadersRequest{}
func (m *GetShardLeadersRequest) String() string { return proto.CompactTextString(m) }
func (*GetShardLeadersRequest) ProtoMessage() {}
func (*GetShardLeadersRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{12}
return fileDescriptor_aab7cc9a69ed26e8, []int{13}
}
func (m *GetShardLeadersRequest) XXX_Unmarshal(b []byte) error {
@ -955,7 +1026,7 @@ func (m *GetShardLeadersResponse) Reset() { *m = GetShardLeadersResponse
func (m *GetShardLeadersResponse) String() string { return proto.CompactTextString(m) }
func (*GetShardLeadersResponse) ProtoMessage() {}
func (*GetShardLeadersResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{13}
return fileDescriptor_aab7cc9a69ed26e8, []int{14}
}
func (m *GetShardLeadersResponse) XXX_Unmarshal(b []byte) error {
@ -1003,7 +1074,7 @@ func (m *ShardLeadersList) Reset() { *m = ShardLeadersList{} }
func (m *ShardLeadersList) String() string { return proto.CompactTextString(m) }
func (*ShardLeadersList) ProtoMessage() {}
func (*ShardLeadersList) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{14}
return fileDescriptor_aab7cc9a69ed26e8, []int{15}
}
func (m *ShardLeadersList) XXX_Unmarshal(b []byte) error {
@ -1059,7 +1130,7 @@ func (m *LoadMetaInfo) Reset() { *m = LoadMetaInfo{} }
func (m *LoadMetaInfo) String() string { return proto.CompactTextString(m) }
func (*LoadMetaInfo) ProtoMessage() {}
func (*LoadMetaInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{15}
return fileDescriptor_aab7cc9a69ed26e8, []int{16}
}
func (m *LoadMetaInfo) XXX_Unmarshal(b []byte) error {
@ -1121,7 +1192,7 @@ func (m *WatchDmChannelsRequest) Reset() { *m = WatchDmChannelsRequest{}
func (m *WatchDmChannelsRequest) String() string { return proto.CompactTextString(m) }
func (*WatchDmChannelsRequest) ProtoMessage() {}
func (*WatchDmChannelsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{16}
return fileDescriptor_aab7cc9a69ed26e8, []int{17}
}
func (m *WatchDmChannelsRequest) XXX_Unmarshal(b []byte) error {
@ -1228,7 +1299,7 @@ func (m *WatchDeltaChannelsRequest) Reset() { *m = WatchDeltaChannelsReq
func (m *WatchDeltaChannelsRequest) String() string { return proto.CompactTextString(m) }
func (*WatchDeltaChannelsRequest) ProtoMessage() {}
func (*WatchDeltaChannelsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{17}
return fileDescriptor_aab7cc9a69ed26e8, []int{18}
}
func (m *WatchDeltaChannelsRequest) XXX_Unmarshal(b []byte) error {
@ -1314,7 +1385,7 @@ func (m *SegmentLoadInfo) Reset() { *m = SegmentLoadInfo{} }
func (m *SegmentLoadInfo) String() string { return proto.CompactTextString(m) }
func (*SegmentLoadInfo) ProtoMessage() {}
func (*SegmentLoadInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{18}
return fileDescriptor_aab7cc9a69ed26e8, []int{19}
}
func (m *SegmentLoadInfo) XXX_Unmarshal(b []byte) error {
@ -1444,7 +1515,7 @@ func (m *FieldIndexInfo) Reset() { *m = FieldIndexInfo{} }
func (m *FieldIndexInfo) String() string { return proto.CompactTextString(m) }
func (*FieldIndexInfo) ProtoMessage() {}
func (*FieldIndexInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{19}
return fileDescriptor_aab7cc9a69ed26e8, []int{20}
}
func (m *FieldIndexInfo) XXX_Unmarshal(b []byte) error {
@ -1540,7 +1611,7 @@ func (m *LoadSegmentsRequest) Reset() { *m = LoadSegmentsRequest{} }
func (m *LoadSegmentsRequest) String() string { return proto.CompactTextString(m) }
func (*LoadSegmentsRequest) ProtoMessage() {}
func (*LoadSegmentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{20}
return fileDescriptor_aab7cc9a69ed26e8, []int{21}
}
func (m *LoadSegmentsRequest) XXX_Unmarshal(b []byte) error {
@ -1642,7 +1713,7 @@ func (m *ReleaseSegmentsRequest) Reset() { *m = ReleaseSegmentsRequest{}
func (m *ReleaseSegmentsRequest) String() string { return proto.CompactTextString(m) }
func (*ReleaseSegmentsRequest) ProtoMessage() {}
func (*ReleaseSegmentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{21}
return fileDescriptor_aab7cc9a69ed26e8, []int{22}
}
func (m *ReleaseSegmentsRequest) XXX_Unmarshal(b []byte) error {
@ -1727,7 +1798,7 @@ func (m *SearchRequest) Reset() { *m = SearchRequest{} }
func (m *SearchRequest) String() string { return proto.CompactTextString(m) }
func (*SearchRequest) ProtoMessage() {}
func (*SearchRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{22}
return fileDescriptor_aab7cc9a69ed26e8, []int{23}
}
func (m *SearchRequest) XXX_Unmarshal(b []byte) error {
@ -1798,7 +1869,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{23}
return fileDescriptor_aab7cc9a69ed26e8, []int{24}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
@ -1867,7 +1938,7 @@ func (m *SyncReplicaSegmentsRequest) Reset() { *m = SyncReplicaSegmentsR
func (m *SyncReplicaSegmentsRequest) String() string { return proto.CompactTextString(m) }
func (*SyncReplicaSegmentsRequest) ProtoMessage() {}
func (*SyncReplicaSegmentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{24}
return fileDescriptor_aab7cc9a69ed26e8, []int{25}
}
func (m *SyncReplicaSegmentsRequest) XXX_Unmarshal(b []byte) error {
@ -1922,7 +1993,7 @@ func (m *ReplicaSegmentsInfo) Reset() { *m = ReplicaSegmentsInfo{} }
func (m *ReplicaSegmentsInfo) String() string { return proto.CompactTextString(m) }
func (*ReplicaSegmentsInfo) ProtoMessage() {}
func (*ReplicaSegmentsInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{25}
return fileDescriptor_aab7cc9a69ed26e8, []int{26}
}
func (m *ReplicaSegmentsInfo) XXX_Unmarshal(b []byte) error {
@ -1978,7 +2049,7 @@ func (m *HandoffSegmentsRequest) Reset() { *m = HandoffSegmentsRequest{}
func (m *HandoffSegmentsRequest) String() string { return proto.CompactTextString(m) }
func (*HandoffSegmentsRequest) ProtoMessage() {}
func (*HandoffSegmentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{26}
return fileDescriptor_aab7cc9a69ed26e8, []int{27}
}
func (m *HandoffSegmentsRequest) XXX_Unmarshal(b []byte) error {
@ -2036,7 +2107,7 @@ func (m *LoadBalanceRequest) Reset() { *m = LoadBalanceRequest{} }
func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) }
func (*LoadBalanceRequest) ProtoMessage() {}
func (*LoadBalanceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{27}
return fileDescriptor_aab7cc9a69ed26e8, []int{28}
}
func (m *LoadBalanceRequest) XXX_Unmarshal(b []byte) error {
@ -2114,7 +2185,7 @@ func (m *DmChannelWatchInfo) Reset() { *m = DmChannelWatchInfo{} }
func (m *DmChannelWatchInfo) String() string { return proto.CompactTextString(m) }
func (*DmChannelWatchInfo) ProtoMessage() {}
func (*DmChannelWatchInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{28}
return fileDescriptor_aab7cc9a69ed26e8, []int{29}
}
func (m *DmChannelWatchInfo) XXX_Unmarshal(b []byte) error {
@ -2185,7 +2256,7 @@ func (m *QueryChannelInfo) Reset() { *m = QueryChannelInfo{} }
func (m *QueryChannelInfo) String() string { return proto.CompactTextString(m) }
func (*QueryChannelInfo) ProtoMessage() {}
func (*QueryChannelInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{29}
return fileDescriptor_aab7cc9a69ed26e8, []int{30}
}
func (m *QueryChannelInfo) XXX_Unmarshal(b []byte) error {
@ -2254,7 +2325,7 @@ func (m *PartitionStates) Reset() { *m = PartitionStates{} }
func (m *PartitionStates) String() string { return proto.CompactTextString(m) }
func (*PartitionStates) ProtoMessage() {}
func (*PartitionStates) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{30}
return fileDescriptor_aab7cc9a69ed26e8, []int{31}
}
func (m *PartitionStates) XXX_Unmarshal(b []byte) error {
@ -2322,7 +2393,7 @@ func (m *SegmentInfo) Reset() { *m = SegmentInfo{} }
func (m *SegmentInfo) String() string { return proto.CompactTextString(m) }
func (*SegmentInfo) ProtoMessage() {}
func (*SegmentInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{31}
return fileDescriptor_aab7cc9a69ed26e8, []int{32}
}
func (m *SegmentInfo) XXX_Unmarshal(b []byte) error {
@ -2467,7 +2538,7 @@ func (m *CollectionInfo) Reset() { *m = CollectionInfo{} }
func (m *CollectionInfo) String() string { return proto.CompactTextString(m) }
func (*CollectionInfo) ProtoMessage() {}
func (*CollectionInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{32}
return fileDescriptor_aab7cc9a69ed26e8, []int{33}
}
func (m *CollectionInfo) XXX_Unmarshal(b []byte) error {
@ -2563,7 +2634,7 @@ func (m *UnsubscribeChannels) Reset() { *m = UnsubscribeChannels{} }
func (m *UnsubscribeChannels) String() string { return proto.CompactTextString(m) }
func (*UnsubscribeChannels) ProtoMessage() {}
func (*UnsubscribeChannels) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{33}
return fileDescriptor_aab7cc9a69ed26e8, []int{34}
}
func (m *UnsubscribeChannels) XXX_Unmarshal(b []byte) error {
@ -2610,7 +2681,7 @@ func (m *UnsubscribeChannelInfo) Reset() { *m = UnsubscribeChannelInfo{}
func (m *UnsubscribeChannelInfo) String() string { return proto.CompactTextString(m) }
func (*UnsubscribeChannelInfo) ProtoMessage() {}
func (*UnsubscribeChannelInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{34}
return fileDescriptor_aab7cc9a69ed26e8, []int{35}
}
func (m *UnsubscribeChannelInfo) XXX_Unmarshal(b []byte) error {
@ -2660,7 +2731,7 @@ func (m *SegmentChangeInfo) Reset() { *m = SegmentChangeInfo{} }
func (m *SegmentChangeInfo) String() string { return proto.CompactTextString(m) }
func (*SegmentChangeInfo) ProtoMessage() {}
func (*SegmentChangeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{35}
return fileDescriptor_aab7cc9a69ed26e8, []int{36}
}
func (m *SegmentChangeInfo) XXX_Unmarshal(b []byte) error {
@ -2721,7 +2792,7 @@ func (m *SealedSegmentsChangeInfo) Reset() { *m = SealedSegmentsChangeIn
func (m *SealedSegmentsChangeInfo) String() string { return proto.CompactTextString(m) }
func (*SealedSegmentsChangeInfo) ProtoMessage() {}
func (*SealedSegmentsChangeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_aab7cc9a69ed26e8, []int{36}
return fileDescriptor_aab7cc9a69ed26e8, []int{37}
}
func (m *SealedSegmentsChangeInfo) XXX_Unmarshal(b []byte) error {
@ -2767,6 +2838,7 @@ func init() {
proto.RegisterType((*ShowPartitionsResponse)(nil), "milvus.proto.query.ShowPartitionsResponse")
proto.RegisterType((*LoadCollectionRequest)(nil), "milvus.proto.query.LoadCollectionRequest")
proto.RegisterType((*ReleaseCollectionRequest)(nil), "milvus.proto.query.ReleaseCollectionRequest")
proto.RegisterType((*GetStatisticsRequest)(nil), "milvus.proto.query.GetStatisticsRequest")
proto.RegisterType((*LoadPartitionsRequest)(nil), "milvus.proto.query.LoadPartitionsRequest")
proto.RegisterType((*ReleasePartitionsRequest)(nil), "milvus.proto.query.ReleasePartitionsRequest")
proto.RegisterType((*GetPartitionStatesRequest)(nil), "milvus.proto.query.GetPartitionStatesRequest")
@ -2804,190 +2876,194 @@ func init() {
func init() { proto.RegisterFile("query_coord.proto", fileDescriptor_aab7cc9a69ed26e8) }
var fileDescriptor_aab7cc9a69ed26e8 = []byte{
// 2928 bytes of a gzipped FileDescriptorProto
// 2977 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3a, 0xc9, 0x8f, 0x1c, 0x57,
0xf9, 0x53, 0xbd, 0x4d, 0xf7, 0xd7, 0x5b, 0xf9, 0x8d, 0x3d, 0xee, 0xf4, 0xcf, 0x4e, 0x9c, 0x72,
0x9c, 0xcc, 0x6f, 0x42, 0xc6, 0x66, 0x1c, 0xa2, 0x04, 0x82, 0x84, 0x3d, 0x13, 0x4f, 0x06, 0xdb,
0x93, 0xa1, 0xda, 0x0e, 0xc8, 0x8a, 0xd4, 0x54, 0x77, 0xbd, 0xe9, 0x29, 0xb9, 0x96, 0x76, 0xbd,
0xea, 0x71, 0x26, 0x67, 0x84, 0xc4, 0x76, 0x40, 0x5c, 0x51, 0xc4, 0x01, 0x0e, 0x48, 0x44, 0x5c,
0xb8, 0x20, 0x21, 0xc4, 0x8d, 0x2b, 0x12, 0x7f, 0x00, 0x47, 0x0e, 0x70, 0x45, 0x5c, 0xd1, 0xdb,
0x6a, 0x2f, 0x77, 0x8f, 0x27, 0x4e, 0x82, 0xc4, 0xad, 0xea, 0x7b, 0xcb, 0xb7, 0x6f, 0xef, 0x3d,
0x38, 0xf3, 0x68, 0x86, 0xfd, 0xe3, 0xe1, 0xd8, 0xf3, 0x7c, 0x73, 0x63, 0xea, 0x7b, 0x81, 0x87,
0x90, 0x63, 0xd9, 0x47, 0x33, 0xc2, 0xff, 0x36, 0xd8, 0x78, 0xbf, 0x35, 0xf6, 0x1c, 0xc7, 0x73,
0x39, 0xac, 0xdf, 0x8a, 0xcf, 0xe8, 0x77, 0x2c, 0x37, 0xc0, 0xbe, 0x6b, 0xd8, 0x72, 0x94, 0x8c,
0x0f, 0xb1, 0x63, 0x88, 0x3f, 0xd5, 0x34, 0x02, 0x23, 0xbe, 0xbf, 0xf6, 0x3d, 0x05, 0x56, 0x07,
0x87, 0xde, 0xe3, 0x2d, 0xcf, 0xb6, 0xf1, 0x38, 0xb0, 0x3c, 0x97, 0xe8, 0xf8, 0xd1, 0x0c, 0x93,
0x00, 0x5d, 0x83, 0xca, 0xc8, 0x20, 0xb8, 0xa7, 0x5c, 0x52, 0xd6, 0x9a, 0x9b, 0x17, 0x36, 0x12,
0x94, 0x08, 0x12, 0xee, 0x92, 0xc9, 0x4d, 0x83, 0x60, 0x9d, 0xcd, 0x44, 0x08, 0x2a, 0xe6, 0x68,
0x77, 0xbb, 0x57, 0xba, 0xa4, 0xac, 0x95, 0x75, 0xf6, 0x8d, 0x5e, 0x82, 0xf6, 0x38, 0xdc, 0x7b,
0x77, 0x9b, 0xf4, 0xca, 0x97, 0xca, 0x6b, 0x65, 0x3d, 0x09, 0xd4, 0xfe, 0xa6, 0xc0, 0xf9, 0x0c,
0x19, 0x64, 0xea, 0xb9, 0x04, 0xa3, 0xeb, 0x50, 0x23, 0x81, 0x11, 0xcc, 0x88, 0xa0, 0xe4, 0xff,
0x72, 0x29, 0x19, 0xb0, 0x29, 0xba, 0x98, 0x9a, 0x45, 0x5b, 0xca, 0x41, 0x8b, 0xbe, 0x0c, 0x67,
0x2d, 0xf7, 0x2e, 0x76, 0x3c, 0xff, 0x78, 0x38, 0xc5, 0xfe, 0x18, 0xbb, 0x81, 0x31, 0xc1, 0x92,
0xc6, 0x15, 0x39, 0xb6, 0x1f, 0x0d, 0xa1, 0x37, 0xe0, 0x3c, 0xd7, 0x12, 0xc1, 0xfe, 0x91, 0x35,
0xc6, 0x43, 0xe3, 0xc8, 0xb0, 0x6c, 0x63, 0x64, 0xe3, 0x5e, 0xe5, 0x52, 0x79, 0xad, 0xae, 0x9f,
0x63, 0xc3, 0x03, 0x3e, 0x7a, 0x43, 0x0e, 0x6a, 0xbf, 0x52, 0xe0, 0x1c, 0xe5, 0x70, 0xdf, 0xf0,
0x03, 0xeb, 0x19, 0xc8, 0x59, 0x83, 0x56, 0x9c, 0xb7, 0x5e, 0x99, 0x8d, 0x25, 0x60, 0x74, 0xce,
0x54, 0xa2, 0xa7, 0x32, 0xa9, 0x30, 0x36, 0x13, 0x30, 0xed, 0x97, 0xc2, 0x20, 0xe2, 0x74, 0x9e,
0x46, 0x11, 0x69, 0x9c, 0xa5, 0x2c, 0xce, 0xa7, 0x50, 0x83, 0xf6, 0x77, 0x05, 0xce, 0xdd, 0xf1,
0x0c, 0x33, 0x32, 0x98, 0xcf, 0x5e, 0x9c, 0x5f, 0x87, 0x1a, 0xf7, 0xae, 0x5e, 0x85, 0xe1, 0xba,
0x92, 0xc4, 0x25, 0x3c, 0x2f, 0xa2, 0x70, 0xc0, 0x00, 0xba, 0x58, 0x84, 0xae, 0x40, 0xc7, 0xc7,
0x53, 0xdb, 0x1a, 0x1b, 0x43, 0x77, 0xe6, 0x8c, 0xb0, 0xdf, 0xab, 0x5e, 0x52, 0xd6, 0xaa, 0x7a,
0x5b, 0x40, 0xf7, 0x18, 0x50, 0xfb, 0xb9, 0x02, 0x3d, 0x1d, 0xdb, 0xd8, 0x20, 0xf8, 0xf3, 0x64,
0x76, 0x15, 0x6a, 0xae, 0x67, 0xe2, 0xdd, 0x6d, 0xc6, 0x6c, 0x59, 0x17, 0x7f, 0xda, 0x8f, 0x4a,
0x5c, 0x11, 0x5f, 0x70, 0xbb, 0x8e, 0x29, 0xab, 0xfa, 0xe9, 0x28, 0xab, 0x96, 0xa7, 0xac, 0x3f,
0x45, 0xca, 0xfa, 0xa2, 0x0b, 0x24, 0x52, 0x68, 0x35, 0xa1, 0xd0, 0x5f, 0x2b, 0xf0, 0xdc, 0x0e,
0x0e, 0x42, 0xf2, 0xa9, 0x3f, 0xe3, 0x2f, 0x68, 0xb0, 0xfa, 0x44, 0x81, 0x7e, 0x1e, 0xad, 0xa7,
0x09, 0x58, 0x0f, 0x60, 0x35, 0xc4, 0x31, 0x34, 0x31, 0x19, 0xfb, 0xd6, 0x94, 0xa9, 0x91, 0x85,
0xae, 0xe6, 0xe6, 0xe5, 0x8d, 0x6c, 0x4a, 0xde, 0x48, 0x53, 0x70, 0x2e, 0xdc, 0x62, 0x3b, 0xb6,
0x83, 0xf6, 0x13, 0x05, 0xce, 0xed, 0xe0, 0x60, 0x80, 0x27, 0x0e, 0x76, 0x83, 0x5d, 0xf7, 0xc0,
0x7b, 0x7a, 0xb9, 0x3e, 0x0f, 0x40, 0xc4, 0x3e, 0x61, 0x58, 0x8d, 0x41, 0x16, 0x91, 0x31, 0xcb,
0xfe, 0x69, 0x7a, 0x4e, 0x23, 0xbb, 0xaf, 0x40, 0xd5, 0x72, 0x0f, 0x3c, 0x29, 0xaa, 0x17, 0xf2,
0x44, 0x15, 0x47, 0xc6, 0x67, 0x6b, 0x2e, 0xa7, 0xe2, 0xd0, 0xf0, 0xcd, 0x3b, 0xd8, 0x30, 0xb1,
0x7f, 0x0a, 0x73, 0x4b, 0xb3, 0x5d, 0xca, 0x61, 0xfb, 0xc7, 0x0a, 0x9c, 0xcf, 0x20, 0x3c, 0x0d,
0xdf, 0x6f, 0x43, 0x8d, 0xd0, 0xcd, 0x24, 0xe3, 0x2f, 0xe5, 0x32, 0x1e, 0x43, 0x77, 0xc7, 0x22,
0x81, 0x2e, 0xd6, 0x68, 0x1e, 0xa8, 0xe9, 0x31, 0xf4, 0x22, 0xb4, 0xc6, 0x87, 0x86, 0xeb, 0x62,
0x7b, 0xe8, 0x1a, 0x0e, 0x17, 0x40, 0x43, 0x6f, 0x0a, 0xd8, 0x9e, 0xe1, 0x60, 0xf4, 0x1c, 0xd4,
0xa9, 0xcb, 0x0e, 0x2d, 0x53, 0xaa, 0x7f, 0x99, 0xb9, 0xb0, 0x49, 0xd0, 0x45, 0x00, 0x36, 0x64,
0x98, 0xa6, 0xcf, 0xd3, 0x68, 0x43, 0x6f, 0x50, 0xc8, 0x0d, 0x0a, 0xd0, 0x7e, 0xaa, 0x40, 0x8b,
0xc6, 0xec, 0xbb, 0x38, 0x30, 0xa8, 0x1e, 0xd0, 0x5b, 0xd0, 0xb0, 0x3d, 0xc3, 0x1c, 0x06, 0xc7,
0x53, 0x8e, 0xaa, 0x93, 0x96, 0x35, 0x67, 0x81, 0x2e, 0xba, 0x77, 0x3c, 0xc5, 0x7a, 0xdd, 0x16,
0x5f, 0x8b, 0xc8, 0x3b, 0xe3, 0xca, 0xe5, 0x1c, 0x57, 0xfe, 0x7e, 0x15, 0x56, 0xbf, 0x6d, 0x04,
0xe3, 0xc3, 0x6d, 0x67, 0x8b, 0x33, 0x79, 0x0a, 0x23, 0x88, 0x62, 0x5b, 0x29, 0x1e, 0xdb, 0x3e,
0xb5, 0xd8, 0x19, 0xda, 0x79, 0x35, 0xcf, 0xce, 0x69, 0x91, 0xbd, 0xf1, 0xbe, 0x50, 0x55, 0xcc,
0xce, 0x63, 0x39, 0xa8, 0xf6, 0x34, 0x39, 0x68, 0x0b, 0xda, 0xf8, 0xc3, 0xb1, 0x3d, 0xa3, 0x3a,
0x67, 0xd8, 0x97, 0x19, 0xf6, 0xe7, 0x73, 0xb0, 0xc7, 0x9d, 0xac, 0x25, 0x16, 0xed, 0x0a, 0x1a,
0xb8, 0xaa, 0x1d, 0x1c, 0x18, 0xbd, 0x3a, 0x23, 0xe3, 0x52, 0x91, 0xaa, 0xa5, 0x7d, 0x70, 0x75,
0xd3, 0x3f, 0x74, 0x01, 0x1a, 0x22, 0xe3, 0xed, 0x6e, 0xf7, 0x1a, 0x4c, 0x7c, 0x11, 0x00, 0x19,
0xd0, 0x16, 0x11, 0x48, 0x50, 0x08, 0x8c, 0xc2, 0xb7, 0xf3, 0x10, 0xe4, 0x2b, 0x3b, 0x4e, 0x39,
0x79, 0xc7, 0x0d, 0xfc, 0x63, 0xbd, 0x45, 0x62, 0xa0, 0xfe, 0x10, 0xce, 0x64, 0xa6, 0x20, 0x15,
0xca, 0x0f, 0xf1, 0x31, 0x33, 0x90, 0xb2, 0x4e, 0x3f, 0xd1, 0xeb, 0x50, 0x3d, 0x32, 0xec, 0x19,
0x66, 0x06, 0x30, 0x5f, 0x46, 0x7c, 0xf2, 0x57, 0x4b, 0x6f, 0x2a, 0xda, 0xc7, 0x25, 0x78, 0x8e,
0xd3, 0x86, 0xed, 0xc0, 0xf8, 0x7c, 0x6d, 0x31, 0xb4, 0xb3, 0xca, 0x89, 0xec, 0xec, 0x22, 0x80,
0x2c, 0x56, 0x2c, 0x53, 0xa4, 0xf7, 0x50, 0x4b, 0x66, 0xd2, 0x04, 0x1a, 0x27, 0x35, 0x01, 0xed,
0x8f, 0x15, 0xe8, 0x0a, 0xd9, 0xd1, 0x19, 0x2c, 0x80, 0x5c, 0x80, 0x46, 0x98, 0x7a, 0x84, 0x1a,
0x22, 0x00, 0xba, 0x04, 0xcd, 0x98, 0xfb, 0x08, 0x39, 0xc4, 0x41, 0x0b, 0x09, 0x43, 0x16, 0x12,
0x95, 0x58, 0x21, 0x71, 0x11, 0xe0, 0xc0, 0x9e, 0x91, 0xc3, 0x61, 0x60, 0x39, 0x58, 0x72, 0xca,
0x20, 0xf7, 0x2c, 0x07, 0xa3, 0x1b, 0xd0, 0x1a, 0x59, 0xae, 0xed, 0x4d, 0x86, 0x53, 0x23, 0x38,
0x24, 0xbd, 0x5a, 0xa1, 0xc3, 0xdc, 0xb2, 0xb0, 0x6d, 0xde, 0x64, 0x73, 0xf5, 0x26, 0x5f, 0xb3,
0x4f, 0x97, 0xa0, 0xe7, 0xa1, 0xe9, 0xce, 0x9c, 0xa1, 0x77, 0x30, 0xf4, 0xbd, 0xc7, 0xd4, 0xe5,
0x18, 0x0a, 0x77, 0xe6, 0xbc, 0x77, 0xa0, 0x7b, 0x8f, 0x69, 0xe8, 0x6f, 0xd0, 0x24, 0x40, 0x6c,
0x6f, 0x42, 0x7a, 0xf5, 0x85, 0xf6, 0x8f, 0x16, 0xd0, 0xd5, 0x26, 0x35, 0x33, 0xb6, 0xba, 0xb1,
0xd8, 0xea, 0x70, 0x01, 0x7a, 0x19, 0x3a, 0x63, 0xcf, 0x99, 0x1a, 0x4c, 0x42, 0xb7, 0x7c, 0xcf,
0x61, 0xfe, 0x56, 0xd6, 0x53, 0x50, 0xb4, 0x05, 0x4d, 0xcb, 0x35, 0xf1, 0x87, 0xc2, 0x29, 0x9b,
0x0c, 0x8f, 0x96, 0xa7, 0x72, 0x86, 0x68, 0x97, 0xce, 0x65, 0x4a, 0x07, 0x4b, 0x7e, 0x12, 0x9a,
0x91, 0xa4, 0x6f, 0x13, 0xeb, 0x23, 0xdc, 0x6b, 0x71, 0x2d, 0x0a, 0xd8, 0xc0, 0xfa, 0x08, 0xd3,
0x22, 0xd9, 0x72, 0x09, 0xf6, 0x83, 0xa1, 0x30, 0xca, 0x5e, 0x9b, 0xa5, 0xad, 0x36, 0x87, 0x0a,
0x5f, 0xd2, 0x7e, 0x5b, 0x82, 0x4e, 0x12, 0x11, 0xea, 0xc1, 0xf2, 0x01, 0x83, 0x48, 0xeb, 0x91,
0xbf, 0x14, 0x2d, 0x76, 0x69, 0x07, 0x3d, 0x64, 0xb4, 0x30, 0xe3, 0xa9, 0xeb, 0x4d, 0x0e, 0x63,
0x1b, 0x50, 0x23, 0xe0, 0xec, 0xb1, 0x4c, 0x59, 0x66, 0x28, 0x1b, 0x0c, 0xc2, 0xf2, 0x64, 0x0f,
0x96, 0x39, 0x1b, 0xd2, 0x74, 0xe4, 0x2f, 0x1d, 0x19, 0xcd, 0x2c, 0x86, 0x95, 0x9b, 0x8e, 0xfc,
0x45, 0xdb, 0xd0, 0xe2, 0x5b, 0x4e, 0x0d, 0xdf, 0x70, 0xa4, 0xe1, 0xbc, 0x98, 0xeb, 0xee, 0xb7,
0xf1, 0xf1, 0xfb, 0x34, 0x7a, 0xec, 0x1b, 0x96, 0xaf, 0x73, 0x41, 0xef, 0xb3, 0x55, 0x68, 0x0d,
0x54, 0xbe, 0xcb, 0x81, 0x65, 0x63, 0x61, 0x82, 0xcb, 0x2c, 0x19, 0x77, 0x18, 0xfc, 0x96, 0x65,
0x63, 0x6e, 0x65, 0x21, 0x0b, 0x4c, 0xb4, 0x75, 0x6e, 0x64, 0x0c, 0x42, 0x05, 0xab, 0xfd, 0xb5,
0x0c, 0x2b, 0xd4, 0xd7, 0x84, 0xdb, 0x9d, 0x22, 0x1a, 0x5d, 0x04, 0x30, 0x49, 0x30, 0x4c, 0x44,
0xa4, 0x86, 0x49, 0x82, 0x3d, 0x1e, 0x94, 0xde, 0x92, 0x01, 0xa7, 0x5c, 0x5c, 0xeb, 0xa6, 0x7c,
0x3f, 0x9b, 0xdc, 0x9e, 0xaa, 0x1b, 0xbe, 0x0c, 0x6d, 0xe2, 0xcd, 0xfc, 0x31, 0x1e, 0x26, 0xba,
0x92, 0x16, 0x07, 0xee, 0xe5, 0xc7, 0xcc, 0x5a, 0x6e, 0x57, 0x1e, 0x8b, 0x6e, 0xcb, 0xa7, 0x4b,
0x70, 0xf5, 0x74, 0x82, 0xbb, 0x0d, 0x5d, 0xe6, 0x7e, 0xc3, 0xa9, 0x47, 0x78, 0x73, 0x27, 0xbc,
0x36, 0xe5, 0x4d, 0xe1, 0x29, 0xdc, 0x5d, 0x32, 0xd9, 0x17, 0x53, 0xf5, 0x0e, 0x5b, 0x2a, 0x7f,
0x89, 0xf6, 0xb3, 0x12, 0xac, 0x8a, 0x66, 0xf1, 0xf4, 0x8a, 0x2d, 0x4a, 0x33, 0x32, 0x6a, 0x96,
0x9f, 0xd0, 0x7e, 0x55, 0x16, 0x28, 0x83, 0xaa, 0x39, 0x65, 0x50, 0xb2, 0x05, 0xa9, 0x65, 0x5a,
0x90, 0xeb, 0x50, 0x25, 0x63, 0x6f, 0x8a, 0x99, 0x1a, 0x3a, 0x9b, 0x17, 0xf3, 0xd4, 0xb0, 0x6d,
0x04, 0xc6, 0x80, 0x4e, 0xd2, 0xf9, 0x5c, 0xed, 0x1f, 0x0a, 0xb4, 0x07, 0xd8, 0xf0, 0xc7, 0x87,
0x52, 0x18, 0x6f, 0x40, 0xd9, 0xc7, 0x8f, 0x84, 0x2c, 0x5e, 0x2a, 0x10, 0x74, 0x62, 0x89, 0x4e,
0x17, 0xd0, 0xd0, 0x61, 0x3a, 0xb6, 0x8c, 0x45, 0xbc, 0x48, 0x6e, 0xe8, 0x4d, 0xd3, 0xb1, 0x65,
0x56, 0x4f, 0x71, 0x50, 0xce, 0x70, 0xb0, 0x0e, 0x67, 0x0e, 0x7c, 0xcf, 0x19, 0xb2, 0x4a, 0x7d,
0x68, 0xb3, 0x02, 0x9d, 0x89, 0xab, 0xae, 0x77, 0xe9, 0x40, 0xac, 0x6e, 0x8f, 0xb8, 0xad, 0x9e,
0x80, 0xdb, 0x7f, 0x2a, 0xd0, 0xfa, 0x16, 0x1d, 0x92, 0xcc, 0xbe, 0x19, 0x67, 0xf6, 0xe5, 0x02,
0x66, 0x75, 0x1c, 0xf8, 0x16, 0x3e, 0xc2, 0xff, 0x75, 0xec, 0xfe, 0x59, 0x81, 0xfe, 0xe0, 0xd8,
0x1d, 0xeb, 0xdc, 0xa3, 0x4e, 0x6f, 0xf6, 0x97, 0xa1, 0x7d, 0x94, 0x68, 0x94, 0x4a, 0x2c, 0xfc,
0xb7, 0x8e, 0xe2, 0x9d, 0x92, 0x0e, 0xaa, 0xac, 0x87, 0x04, 0xb3, 0x32, 0xc0, 0xbd, 0x92, 0x47,
0x75, 0x8a, 0x38, 0x16, 0x20, 0xba, 0x7e, 0x12, 0xa8, 0xf9, 0xb0, 0x92, 0x33, 0x0f, 0x9d, 0x87,
0x65, 0xd1, 0x94, 0x89, 0x44, 0xc6, 0xfd, 0xd0, 0xa4, 0xda, 0x89, 0x8e, 0x15, 0x2c, 0x33, 0x5b,
0x04, 0x99, 0xe8, 0x05, 0x68, 0x86, 0xd5, 0xb3, 0x99, 0x51, 0x8f, 0x49, 0xb4, 0x3f, 0x28, 0xb0,
0xfa, 0xae, 0xe1, 0x9a, 0xde, 0xc1, 0xc1, 0xe9, 0x25, 0xb7, 0x05, 0x89, 0xc2, 0x7a, 0xd1, 0x96,
0x3d, 0xb1, 0x08, 0xbd, 0x0a, 0x67, 0x7c, 0x1e, 0xc1, 0xcc, 0xa4, 0x68, 0xcb, 0xba, 0x2a, 0x07,
0x42, 0x91, 0xfd, 0xa6, 0x04, 0x88, 0x46, 0xdd, 0x9b, 0x86, 0x6d, 0xb8, 0x63, 0xfc, 0xf4, 0xa4,
0x5f, 0x81, 0x4e, 0x22, 0x57, 0x84, 0xa7, 0xfb, 0xf1, 0x64, 0x41, 0xd0, 0x6d, 0xe8, 0x8c, 0x38,
0xaa, 0xa1, 0x8f, 0x0d, 0xe2, 0xb9, 0x2c, 0x08, 0x76, 0xf2, 0xbb, 0xf3, 0x7b, 0xbe, 0x35, 0x99,
0x60, 0x7f, 0xcb, 0x73, 0x4d, 0x1e, 0xad, 0xdb, 0x23, 0x49, 0x26, 0x5d, 0x4a, 0x95, 0x13, 0x25,
0x4e, 0xd9, 0x15, 0x42, 0x98, 0x39, 0x99, 0x28, 0x08, 0x36, 0xec, 0x48, 0x10, 0x51, 0xd4, 0x54,
0xf9, 0xc0, 0xa0, 0xf8, 0x70, 0x26, 0x27, 0x91, 0x69, 0xbf, 0x53, 0x00, 0x85, 0xfd, 0x11, 0xeb,
0x48, 0x98, 0x85, 0xa5, 0x97, 0x2a, 0x39, 0xc1, 0xfb, 0x02, 0x34, 0x4c, 0xb9, 0x52, 0x78, 0x44,
0x04, 0xa0, 0x3e, 0xc3, 0xd9, 0x18, 0xd2, 0xac, 0x87, 0x4d, 0x59, 0x6d, 0x73, 0xe0, 0x1d, 0x06,
0x4b, 0xe6, 0xc1, 0x4a, 0x3a, 0x0f, 0xc6, 0xcf, 0x1e, 0xaa, 0x89, 0xb3, 0x07, 0xed, 0x93, 0x12,
0xa8, 0x2c, 0xa2, 0x6d, 0x45, 0x8d, 0xc9, 0x42, 0x44, 0x5f, 0x86, 0xb6, 0xb8, 0xff, 0x4a, 0x10,
0xde, 0x7a, 0x14, 0xdb, 0x0c, 0x5d, 0x83, 0xb3, 0x7c, 0x92, 0x8f, 0xc9, 0xcc, 0x8e, 0x0a, 0x4d,
0x5e, 0xf5, 0xa1, 0x47, 0x3c, 0x94, 0xd2, 0x21, 0xb9, 0xe2, 0x3e, 0xac, 0x4e, 0x6c, 0x6f, 0x64,
0xd8, 0xc3, 0xa4, 0x7a, 0x0a, 0x9a, 0xaa, 0xac, 0xc5, 0x9f, 0xe5, 0xcb, 0x07, 0x71, 0x1d, 0x12,
0xb4, 0x43, 0x5b, 0x5d, 0xfc, 0x30, 0x2c, 0x04, 0xc4, 0xb1, 0xf2, 0x22, 0x75, 0x40, 0x8b, 0x2e,
0x94, 0x7f, 0xda, 0xc7, 0x0a, 0x74, 0x53, 0xc7, 0x87, 0xe9, 0x86, 0x49, 0xc9, 0x36, 0x4c, 0x6f,
0x42, 0x95, 0x76, 0x11, 0x3c, 0xde, 0x75, 0xf2, 0x8b, 0xf9, 0xe4, 0xae, 0x3a, 0x5f, 0x80, 0xae,
0xc2, 0x4a, 0xce, 0x65, 0x8b, 0xb0, 0x01, 0x94, 0xbd, 0x6b, 0xd1, 0x7e, 0x5f, 0x81, 0x66, 0x4c,
0x1e, 0x73, 0x7a, 0xbd, 0x45, 0xce, 0x83, 0x52, 0xec, 0x95, 0xb3, 0xec, 0x15, 0xdc, 0x36, 0x50,
0xbb, 0x73, 0xb0, 0xc3, 0xab, 0x64, 0x51, 0xb2, 0x3b, 0xd8, 0x61, 0xcd, 0x07, 0x35, 0xc9, 0x99,
0xc3, 0xbb, 0x34, 0xee, 0x4e, 0xcb, 0xee, 0xcc, 0x61, 0x3d, 0x5a, 0xb2, 0x41, 0x58, 0x7e, 0x42,
0x83, 0x50, 0x4f, 0x36, 0x08, 0x09, 0x3f, 0x6a, 0xa4, 0xfd, 0x68, 0xd1, 0xf6, 0xeb, 0x1a, 0xac,
0x8c, 0x7d, 0x6c, 0x04, 0xd8, 0xbc, 0x79, 0xbc, 0x15, 0x0e, 0xf5, 0x9a, 0x2c, 0xaf, 0xe6, 0x0d,
0xa1, 0x5b, 0xd1, 0x39, 0x0a, 0xd7, 0x72, 0x8b, 0x69, 0x39, 0xbf, 0xff, 0x10, 0xba, 0xe1, 0x4a,
0x96, 0xe1, 0x99, 0xfd, 0xa5, 0x1b, 0xbf, 0xf6, 0x53, 0x35, 0x7e, 0x2f, 0x40, 0x33, 0x3a, 0x4d,
0x20, 0xbd, 0x0e, 0x8f, 0x7c, 0xe1, 0x71, 0x02, 0x49, 0x04, 0x83, 0x6e, 0x32, 0x18, 0xfc, 0xa5,
0x0c, 0x9d, 0xa8, 0xe4, 0x5f, 0x38, 0x14, 0x2c, 0x72, 0x69, 0xb8, 0x07, 0x6a, 0x94, 0x50, 0x99,
0x94, 0x9e, 0xd8, 0xb5, 0xa4, 0x4f, 0xe8, 0xbb, 0xd3, 0x94, 0xcf, 0x25, 0xce, 0x40, 0x2b, 0x27,
0x3a, 0x03, 0x3d, 0xe5, 0xdd, 0xd2, 0x75, 0x38, 0x17, 0x26, 0xd1, 0x04, 0xdb, 0xbc, 0xa2, 0x3e,
0x2b, 0x07, 0xf7, 0xe3, 0xec, 0x17, 0xb8, 0xf1, 0x72, 0x91, 0x1b, 0xa7, 0xd5, 0x58, 0xcf, 0xa8,
0x31, 0x7b, 0xc5, 0xd5, 0xc8, 0xbb, 0xe2, 0xba, 0x0f, 0x2b, 0xf7, 0x5d, 0x32, 0x1b, 0x91, 0xb1,
0x6f, 0x8d, 0x70, 0x58, 0x5a, 0x2e, 0xa2, 0xd6, 0x3e, 0xd4, 0x53, 0xd5, 0x69, 0xf8, 0xaf, 0xfd,
0x50, 0x81, 0xd5, 0xec, 0xbe, 0xcc, 0x62, 0xa2, 0x60, 0xa0, 0x24, 0x82, 0xc1, 0x77, 0x60, 0x25,
0xda, 0x3e, 0x59, 0xf7, 0x16, 0x54, 0x76, 0x39, 0x84, 0xeb, 0x28, 0xda, 0x43, 0xc2, 0xb4, 0x7f,
0x29, 0xe1, 0x29, 0x23, 0x85, 0x4d, 0xd8, 0xd9, 0x29, 0x4d, 0x50, 0x9e, 0x6b, 0x5b, 0x6e, 0xd8,
0xa2, 0x0a, 0x1e, 0x39, 0x50, 0xb4, 0xa8, 0xef, 0x42, 0x57, 0x4c, 0x0a, 0xf3, 0xcc, 0x82, 0x95,
0x55, 0x87, 0xaf, 0x0b, 0x33, 0xcc, 0x15, 0xe8, 0x78, 0x07, 0x07, 0x71, 0x7c, 0x3c, 0x50, 0xb6,
0x05, 0x54, 0x20, 0xfc, 0x26, 0xa8, 0x72, 0xda, 0x49, 0x33, 0x5b, 0x57, 0x2c, 0x0c, 0x2b, 0xb4,
0x1f, 0x28, 0xd0, 0x4b, 0xe6, 0xb9, 0x18, 0xfb, 0x27, 0xaf, 0xd3, 0xbe, 0x96, 0xbc, 0x0e, 0xba,
0xf2, 0x04, 0x7a, 0x22, 0x3c, 0xe2, 0x3c, 0x61, 0xfd, 0x1b, 0xd0, 0x08, 0xdb, 0x07, 0xd4, 0x84,
0xe5, 0xfb, 0xee, 0x6d, 0xd7, 0x7b, 0xec, 0xaa, 0x4b, 0x68, 0x19, 0xca, 0x37, 0x6c, 0x5b, 0x55,
0x50, 0x1b, 0x1a, 0x83, 0xc0, 0xc7, 0x86, 0x63, 0xb9, 0x13, 0xb5, 0x84, 0x3a, 0x00, 0xef, 0x5a,
0x24, 0xf0, 0x7c, 0x6b, 0x6c, 0xd8, 0x6a, 0x79, 0xfd, 0x23, 0xe8, 0x24, 0xbd, 0x1e, 0xb5, 0xa0,
0xbe, 0xe7, 0x05, 0xef, 0x7c, 0x68, 0x91, 0x40, 0x5d, 0xa2, 0xf3, 0xf7, 0xbc, 0x60, 0xdf, 0xc7,
0x04, 0xbb, 0x81, 0xaa, 0x20, 0x80, 0xda, 0x7b, 0xee, 0xb6, 0x45, 0x1e, 0xaa, 0x25, 0xb4, 0x22,
0x92, 0xb2, 0x61, 0xef, 0x0a, 0x57, 0x52, 0xcb, 0x74, 0x79, 0xf8, 0x57, 0x41, 0x2a, 0xb4, 0xc2,
0x29, 0x3b, 0xfb, 0xf7, 0xd5, 0x2a, 0x6a, 0x40, 0x95, 0x7f, 0xd6, 0xd6, 0x4d, 0x50, 0xd3, 0x15,
0x25, 0xdd, 0x93, 0x33, 0x11, 0x82, 0xd4, 0x25, 0xca, 0x99, 0x28, 0xe9, 0x55, 0x05, 0x75, 0xa1,
0x19, 0x2b, 0x90, 0xd5, 0x12, 0x05, 0xec, 0xf8, 0xd3, 0xb1, 0x28, 0x95, 0x39, 0x09, 0x54, 0xef,
0xdb, 0x54, 0x12, 0x95, 0xf5, 0x9b, 0x50, 0x97, 0xe1, 0x88, 0x4e, 0x15, 0x22, 0xa2, 0xbf, 0xea,
0x12, 0x3a, 0x03, 0xed, 0xc4, 0xc5, 0xbc, 0xaa, 0x20, 0x04, 0x9d, 0xe4, 0xa3, 0x09, 0xb5, 0xb4,
0xf9, 0x8b, 0x16, 0x00, 0xaf, 0xd7, 0x3c, 0xcf, 0x37, 0xd1, 0x14, 0xd0, 0x0e, 0x0e, 0x68, 0x2e,
0xf2, 0x5c, 0x99, 0x47, 0x08, 0xba, 0x56, 0x50, 0xd6, 0x64, 0xa7, 0x0a, 0x52, 0xfb, 0x45, 0xad,
0x6b, 0x6a, 0xba, 0xb6, 0x84, 0x1c, 0x86, 0xf1, 0x9e, 0xe5, 0xe0, 0x7b, 0xd6, 0xf8, 0x61, 0x58,
0xe8, 0x15, 0x63, 0x4c, 0x4d, 0x95, 0x18, 0x53, 0x61, 0x5f, 0xfc, 0x0c, 0x02, 0xdf, 0x72, 0x27,
0xf2, 0x7a, 0x4f, 0x5b, 0x42, 0x8f, 0xe0, 0xec, 0x0e, 0x66, 0xd8, 0x2d, 0x12, 0x58, 0x63, 0x22,
0x11, 0x6e, 0x16, 0x23, 0xcc, 0x4c, 0x3e, 0x21, 0x4a, 0x1b, 0xba, 0xa9, 0xc7, 0x4d, 0x68, 0x3d,
0xff, 0x86, 0x30, 0xef, 0x21, 0x56, 0xff, 0xd5, 0x85, 0xe6, 0x86, 0xd8, 0x2c, 0xe8, 0x24, 0x1f,
0xf0, 0xa0, 0xff, 0x2f, 0xda, 0x20, 0xf3, 0x46, 0xa1, 0xbf, 0xbe, 0xc8, 0xd4, 0x10, 0xd5, 0x03,
0x6e, 0x4f, 0xf3, 0x50, 0xe5, 0xbe, 0x0f, 0xe9, 0x3f, 0xe9, 0x66, 0x55, 0x5b, 0x42, 0xdf, 0x85,
0x33, 0x99, 0x97, 0x14, 0xe8, 0x4b, 0xf9, 0xfd, 0x7a, 0xfe, 0x83, 0x8b, 0x79, 0x18, 0x1e, 0xa4,
0xbd, 0xa1, 0x98, 0xfa, 0xcc, 0xcb, 0x9b, 0xc5, 0xa9, 0x8f, 0x6d, 0xff, 0x24, 0xea, 0x4f, 0x8c,
0x61, 0xc6, 0xdc, 0x26, 0xdd, 0x39, 0xbc, 0x96, 0x87, 0xa2, 0xf0, 0x39, 0x47, 0x7f, 0x63, 0xd1,
0xe9, 0x71, 0xeb, 0x4a, 0xbe, 0x18, 0xc8, 0x17, 0x5a, 0xee, 0x2b, 0x87, 0x7c, 0xeb, 0xca, 0x7f,
0x80, 0xa0, 0x2d, 0xa1, 0x7b, 0x89, 0x68, 0x88, 0x5e, 0x2e, 0x52, 0x4e, 0xf2, 0x3c, 0x61, 0x9e,
0xdc, 0x86, 0x00, 0x3b, 0x38, 0xb8, 0x8b, 0x03, 0xdf, 0x1a, 0x93, 0xf4, 0xa6, 0xe2, 0x27, 0x9a,
0x20, 0x37, 0x7d, 0x65, 0xee, 0xbc, 0x90, 0xec, 0x11, 0x34, 0x77, 0x70, 0x20, 0x0e, 0x87, 0x08,
0x2a, 0x5c, 0x29, 0x67, 0x48, 0x14, 0x6b, 0xf3, 0x27, 0xc6, 0x23, 0x4a, 0xea, 0x01, 0x03, 0x2a,
0x94, 0x6d, 0xf6, 0x59, 0x45, 0x7e, 0x44, 0x29, 0x78, 0x11, 0xa1, 0x2d, 0x6d, 0xfe, 0x1b, 0xa0,
0xc1, 0x52, 0x04, 0x4d, 0x3d, 0xff, 0xcb, 0x10, 0xcf, 0x20, 0x43, 0x7c, 0x00, 0xdd, 0xd4, 0x7d,
0x78, 0xbe, 0x3e, 0xf3, 0x2f, 0xcd, 0xe7, 0x99, 0xfc, 0x08, 0x50, 0xf6, 0x46, 0x3b, 0x3f, 0x54,
0x14, 0xde, 0x7c, 0xcf, 0xc3, 0xf1, 0x3e, 0x7f, 0x52, 0x12, 0x56, 0xaf, 0xaf, 0x14, 0x79, 0x6b,
0xea, 0xe4, 0xf2, 0xf3, 0x0f, 0xa4, 0xcf, 0x3e, 0xd1, 0x7c, 0x00, 0xdd, 0xd4, 0x3d, 0x4f, 0xbe,
0x76, 0xf3, 0x2f, 0x83, 0xe6, 0xed, 0xfe, 0x19, 0x46, 0x64, 0x13, 0x56, 0x72, 0x4e, 0xef, 0x51,
0x6e, 0x16, 0x29, 0x3e, 0xe6, 0x9f, 0xc7, 0xd0, 0x00, 0x6a, 0xfc, 0x36, 0x07, 0xbd, 0x98, 0xdf,
0x31, 0xc4, 0x6e, 0x7a, 0xfa, 0xf3, 0xee, 0x83, 0xc8, 0xcc, 0x0e, 0xf8, 0xa6, 0x55, 0x16, 0xc2,
0x50, 0xee, 0x65, 0x60, 0xfc, 0x0a, 0xa6, 0x3f, 0xff, 0xd6, 0x45, 0x6e, 0xfa, 0xac, 0x73, 0xc9,
0xcd, 0xd7, 0x1f, 0x6c, 0x4e, 0xac, 0xe0, 0x70, 0x36, 0xa2, 0x42, 0xba, 0xca, 0x67, 0xbe, 0x66,
0x79, 0xe2, 0xeb, 0xaa, 0x24, 0xed, 0x2a, 0xdb, 0xe9, 0x2a, 0xe3, 0x65, 0x3a, 0x1a, 0xd5, 0xd8,
0xef, 0xf5, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xab, 0x05, 0x7f, 0x12, 0x50, 0x30, 0x00, 0x00,
0xf9, 0x53, 0xbd, 0x4c, 0x77, 0x7f, 0xbd, 0x95, 0xdf, 0xd8, 0xe3, 0x4e, 0xff, 0xec, 0x64, 0x52,
0x8e, 0x93, 0xf9, 0x4d, 0x92, 0xb1, 0x19, 0x87, 0x28, 0x81, 0x44, 0xc2, 0x9e, 0x89, 0x27, 0x83,
0xed, 0xc9, 0x50, 0x6d, 0x07, 0x64, 0x45, 0x6a, 0xaa, 0xbb, 0xde, 0xf4, 0x94, 0x5c, 0x4b, 0xbb,
0x5e, 0xf5, 0xd8, 0x93, 0x33, 0x42, 0x62, 0x3b, 0x20, 0xae, 0x28, 0xe2, 0x00, 0x07, 0x24, 0x22,
0x2e, 0x5c, 0x90, 0x10, 0xe2, 0xc6, 0x15, 0x89, 0x3f, 0x00, 0x89, 0x0b, 0x07, 0xb8, 0x72, 0xe0,
0x86, 0xde, 0x52, 0x6b, 0xbf, 0x72, 0xf7, 0xcc, 0xc4, 0x89, 0x23, 0x71, 0xab, 0xfa, 0xde, 0xf2,
0xed, 0xdb, 0x7b, 0x0f, 0xce, 0x3c, 0x9c, 0x60, 0xff, 0xa8, 0x3f, 0xf4, 0x3c, 0xdf, 0x5c, 0x1f,
0xfb, 0x5e, 0xe0, 0x21, 0xe4, 0x58, 0xf6, 0xe1, 0x84, 0xf0, 0xbf, 0x75, 0x36, 0xde, 0x6d, 0x0c,
0x3d, 0xc7, 0xf1, 0x5c, 0x0e, 0xeb, 0x36, 0x92, 0x33, 0xba, 0x2d, 0xcb, 0x0d, 0xb0, 0xef, 0x1a,
0x76, 0x38, 0x4a, 0x86, 0x07, 0xd8, 0x31, 0xc4, 0x9f, 0x6a, 0x1a, 0x81, 0x91, 0xdc, 0x5f, 0xfb,
0x9e, 0x02, 0xcb, 0xbd, 0x03, 0xef, 0xd1, 0xa6, 0x67, 0xdb, 0x78, 0x18, 0x58, 0x9e, 0x4b, 0x74,
0xfc, 0x70, 0x82, 0x49, 0x80, 0xae, 0x42, 0x69, 0x60, 0x10, 0xdc, 0x51, 0x56, 0x94, 0xd5, 0xfa,
0xc6, 0x85, 0xf5, 0x14, 0x25, 0x82, 0x84, 0x3b, 0x64, 0x74, 0xc3, 0x20, 0x58, 0x67, 0x33, 0x11,
0x82, 0x92, 0x39, 0xd8, 0xd9, 0xea, 0x14, 0x56, 0x94, 0xd5, 0xa2, 0xce, 0xbe, 0xd1, 0x4b, 0xd0,
0x1c, 0x46, 0x7b, 0xef, 0x6c, 0x91, 0x4e, 0x71, 0xa5, 0xb8, 0x5a, 0xd4, 0xd3, 0x40, 0xed, 0x6f,
0x0a, 0x9c, 0x9f, 0x22, 0x83, 0x8c, 0x3d, 0x97, 0x60, 0x74, 0x0d, 0x16, 0x49, 0x60, 0x04, 0x13,
0x22, 0x28, 0xf9, 0x3f, 0x29, 0x25, 0x3d, 0x36, 0x45, 0x17, 0x53, 0xa7, 0xd1, 0x16, 0x24, 0x68,
0xd1, 0x57, 0xe0, 0xac, 0xe5, 0xde, 0xc1, 0x8e, 0xe7, 0x1f, 0xf5, 0xc7, 0xd8, 0x1f, 0x62, 0x37,
0x30, 0x46, 0x38, 0xa4, 0x71, 0x29, 0x1c, 0xdb, 0x8b, 0x87, 0xd0, 0x9b, 0x70, 0x9e, 0x6b, 0x89,
0x60, 0xff, 0xd0, 0x1a, 0xe2, 0xbe, 0x71, 0x68, 0x58, 0xb6, 0x31, 0xb0, 0x71, 0xa7, 0xb4, 0x52,
0x5c, 0xad, 0xea, 0xe7, 0xd8, 0x70, 0x8f, 0x8f, 0x5e, 0x0f, 0x07, 0xb5, 0x5f, 0x29, 0x70, 0x8e,
0x72, 0xb8, 0x67, 0xf8, 0x81, 0xf5, 0x14, 0xe4, 0xac, 0x41, 0x23, 0xc9, 0x5b, 0xa7, 0xc8, 0xc6,
0x52, 0x30, 0x3a, 0x67, 0x1c, 0xa2, 0xa7, 0x32, 0x29, 0x31, 0x36, 0x53, 0x30, 0xed, 0x97, 0xc2,
0x20, 0x92, 0x74, 0x9e, 0x46, 0x11, 0x59, 0x9c, 0x85, 0x69, 0x9c, 0x27, 0x50, 0x83, 0xf6, 0x0f,
0x05, 0xce, 0xdd, 0xf6, 0x0c, 0x33, 0x36, 0x98, 0xcf, 0x5f, 0x9c, 0xef, 0xc2, 0x22, 0xf7, 0xae,
0x4e, 0x89, 0xe1, 0xba, 0x9c, 0xc6, 0x25, 0x3c, 0x2f, 0xa6, 0xb0, 0xc7, 0x00, 0xba, 0x58, 0x84,
0x2e, 0x43, 0xcb, 0xc7, 0x63, 0xdb, 0x1a, 0x1a, 0x7d, 0x77, 0xe2, 0x0c, 0xb0, 0xdf, 0x29, 0xaf,
0x28, 0xab, 0x65, 0xbd, 0x29, 0xa0, 0xbb, 0x0c, 0xa8, 0xfd, 0x5c, 0x81, 0x8e, 0x8e, 0x6d, 0x6c,
0x10, 0xfc, 0x45, 0x32, 0xbb, 0x0c, 0x8b, 0xae, 0x67, 0xe2, 0x9d, 0x2d, 0xc6, 0x6c, 0x51, 0x17,
0x7f, 0xda, 0x7f, 0x14, 0x38, 0xbb, 0x8d, 0x03, 0xaa, 0x75, 0x8b, 0x04, 0xd6, 0x30, 0x32, 0xeb,
0x77, 0xa1, 0xe8, 0xe3, 0x87, 0x82, 0xb2, 0x57, 0xd3, 0x94, 0x45, 0x41, 0x4a, 0xb6, 0x52, 0xa7,
0xeb, 0xd0, 0x8b, 0xd0, 0x30, 0x1d, 0xbb, 0x3f, 0x3c, 0x30, 0x5c, 0x17, 0xdb, 0xdc, 0x6e, 0x6a,
0x7a, 0xdd, 0x74, 0xec, 0x4d, 0x01, 0x42, 0xcf, 0x03, 0x10, 0x3c, 0x72, 0xb0, 0x1b, 0xc4, 0x71,
0x25, 0x01, 0x41, 0x6b, 0x70, 0x66, 0xdf, 0xf7, 0x9c, 0x3e, 0x39, 0x30, 0x7c, 0xb3, 0x6f, 0x63,
0xc3, 0xc4, 0x3e, 0xa3, 0xbe, 0xaa, 0xb7, 0xe9, 0x40, 0x8f, 0xc2, 0x6f, 0x33, 0x30, 0xba, 0x06,
0x65, 0x32, 0xf4, 0xc6, 0x98, 0xe9, 0xa0, 0xb5, 0x71, 0x71, 0x7d, 0x3a, 0xee, 0xae, 0x6f, 0x19,
0x81, 0xd1, 0xa3, 0x93, 0x74, 0x3e, 0x57, 0xfb, 0x51, 0x81, 0x1b, 0xe1, 0x33, 0xee, 0xd3, 0x09,
0x43, 0x2d, 0x7f, 0x36, 0x86, 0xba, 0x28, 0x33, 0xd4, 0x3f, 0xc5, 0x86, 0xfa, 0xac, 0x0b, 0x24,
0x36, 0xe6, 0x72, 0xca, 0x98, 0x7f, 0xad, 0xc0, 0x73, 0xdb, 0x38, 0x88, 0xc8, 0xa7, 0xb6, 0x89,
0x9f, 0xd1, 0x40, 0xfd, 0xa9, 0x02, 0x5d, 0x19, 0xad, 0xa7, 0x09, 0xd6, 0xf7, 0x61, 0x39, 0xc2,
0xd1, 0x37, 0x31, 0x19, 0xfa, 0xd6, 0x98, 0xa9, 0x91, 0xb9, 0x5f, 0x7d, 0xe3, 0x92, 0xcc, 0x2d,
0xb2, 0x14, 0x9c, 0x8b, 0xb6, 0xd8, 0x4a, 0xec, 0xa0, 0xfd, 0x44, 0x81, 0x73, 0xd4, 0xdd, 0x85,
0x7f, 0xba, 0xfb, 0xde, 0xc9, 0xe5, 0x9a, 0xf6, 0xfc, 0xc2, 0x94, 0xe7, 0xcf, 0x21, 0x63, 0x56,
0xf9, 0x64, 0xe9, 0x39, 0x8d, 0xec, 0xbe, 0x0a, 0x65, 0xcb, 0xdd, 0xf7, 0x42, 0x51, 0xbd, 0x20,
0x13, 0x55, 0x12, 0x19, 0x9f, 0xad, 0xb9, 0x9c, 0x8a, 0x38, 0x14, 0x9d, 0xc2, 0xdc, 0xb2, 0x6c,
0x17, 0x24, 0x6c, 0xff, 0x58, 0x81, 0xf3, 0x53, 0x08, 0x4f, 0xc3, 0xf7, 0x3b, 0xb0, 0xc8, 0x02,
0x6c, 0xc8, 0xf8, 0x4b, 0x52, 0xc6, 0x13, 0xe8, 0x6e, 0x5b, 0x24, 0xd0, 0xc5, 0x1a, 0xcd, 0x03,
0x35, 0x3b, 0x46, 0x43, 0xbf, 0x08, 0xfb, 0x7d, 0xd7, 0x70, 0xb8, 0x00, 0x6a, 0x7a, 0x5d, 0xc0,
0x76, 0x0d, 0x07, 0xa3, 0xe7, 0xa0, 0x4a, 0x5d, 0xb6, 0x6f, 0x99, 0xa1, 0xfa, 0x2b, 0xcc, 0x85,
0x4d, 0x82, 0x2e, 0x02, 0xb0, 0x21, 0xc3, 0x34, 0x7d, 0x9e, 0x15, 0x6a, 0x7a, 0x8d, 0x42, 0xae,
0x53, 0x80, 0xf6, 0x53, 0x05, 0x1a, 0x34, 0x66, 0xdf, 0xc1, 0x81, 0x41, 0xf5, 0x80, 0xde, 0x86,
0x9a, 0xed, 0x19, 0x66, 0x3f, 0x38, 0x1a, 0x73, 0x54, 0xad, 0xac, 0xac, 0x39, 0x0b, 0x74, 0xd1,
0xdd, 0xa3, 0x31, 0xd6, 0xab, 0xb6, 0xf8, 0x9a, 0x47, 0xde, 0x53, 0xae, 0x5c, 0x94, 0xb8, 0xf2,
0xf7, 0xcb, 0xb0, 0xfc, 0x6d, 0x23, 0x18, 0x1e, 0x6c, 0x39, 0x61, 0x72, 0x3b, 0xb9, 0x11, 0xc4,
0xb1, 0xad, 0x90, 0x8c, 0x6d, 0x9f, 0x59, 0xec, 0x8c, 0xec, 0xbc, 0x2c, 0xb3, 0x73, 0xda, 0x60,
0xac, 0x7f, 0x28, 0x54, 0x95, 0xb0, 0xf3, 0x44, 0x0e, 0x5a, 0x3c, 0x49, 0x0e, 0xda, 0x84, 0x26,
0x7e, 0x3c, 0xb4, 0x27, 0x54, 0xe7, 0x0c, 0x7b, 0x85, 0x61, 0x7f, 0x5e, 0x82, 0x3d, 0xe9, 0x64,
0x0d, 0xb1, 0x68, 0x47, 0xd0, 0xc0, 0x55, 0xed, 0xe0, 0xc0, 0xe8, 0x54, 0x19, 0x19, 0x2b, 0x79,
0xaa, 0x0e, 0xed, 0x83, 0xab, 0x9b, 0xfe, 0xa1, 0x0b, 0x50, 0x13, 0x19, 0x6f, 0x67, 0xab, 0x53,
0x63, 0xe2, 0x8b, 0x01, 0xc8, 0x80, 0xa6, 0x88, 0x40, 0x82, 0x42, 0x60, 0x14, 0xbe, 0x23, 0x43,
0x20, 0x57, 0x76, 0x92, 0x72, 0xf2, 0x9e, 0x1b, 0xf8, 0x47, 0x7a, 0x83, 0x24, 0x40, 0xdd, 0x3e,
0x9c, 0x99, 0x9a, 0x82, 0x54, 0x28, 0x3e, 0xc0, 0x47, 0xcc, 0x40, 0x8a, 0x3a, 0xfd, 0x44, 0x6f,
0x40, 0xf9, 0xd0, 0xb0, 0x27, 0x98, 0x19, 0xc0, 0x6c, 0x19, 0xf1, 0xc9, 0x5f, 0x2b, 0xbc, 0xa5,
0x68, 0x9f, 0x14, 0xe0, 0x39, 0x4e, 0x1b, 0xb6, 0x03, 0xe3, 0x8b, 0xb5, 0xc5, 0xc8, 0xce, 0x4a,
0xc7, 0xb2, 0xb3, 0x8b, 0x00, 0x61, 0xb1, 0x62, 0x99, 0x22, 0xbd, 0x47, 0x5a, 0x32, 0xd3, 0x26,
0x50, 0x3b, 0xae, 0x09, 0x68, 0x7f, 0x2c, 0x41, 0x5b, 0xc8, 0x8e, 0xce, 0x60, 0x01, 0xe4, 0x02,
0xd4, 0xa2, 0xd4, 0x23, 0xd4, 0x10, 0x03, 0xd0, 0x0a, 0xd4, 0x13, 0xee, 0x23, 0xe4, 0x90, 0x04,
0xcd, 0x25, 0x8c, 0xb0, 0x90, 0x28, 0x25, 0x0a, 0x89, 0x8b, 0x00, 0xfb, 0xf6, 0x84, 0x1c, 0xf4,
0x03, 0xcb, 0xc1, 0x21, 0xa7, 0x0c, 0x72, 0xd7, 0x72, 0x30, 0xba, 0x0e, 0x8d, 0x81, 0xe5, 0xda,
0xde, 0xa8, 0x3f, 0x36, 0x82, 0x03, 0xd2, 0x59, 0xcc, 0x75, 0x98, 0x9b, 0x16, 0xb6, 0xcd, 0x1b,
0x6c, 0xae, 0x5e, 0xe7, 0x6b, 0xf6, 0xe8, 0x12, 0xf4, 0x3c, 0xd4, 0xdd, 0x89, 0xd3, 0xf7, 0xf6,
0xfb, 0xbe, 0xf7, 0x88, 0xba, 0x1c, 0x43, 0xe1, 0x4e, 0x9c, 0x0f, 0xf6, 0x75, 0xef, 0x11, 0x0d,
0xfd, 0x35, 0x9a, 0x04, 0x88, 0xed, 0x8d, 0x48, 0xa7, 0x3a, 0xd7, 0xfe, 0xf1, 0x02, 0xba, 0xda,
0xa4, 0x66, 0xc6, 0x56, 0xd7, 0xe6, 0x5b, 0x1d, 0x2d, 0x40, 0x2f, 0x43, 0x6b, 0xe8, 0x39, 0x63,
0x83, 0x49, 0xe8, 0xa6, 0xef, 0x39, 0xcc, 0xdf, 0x8a, 0x7a, 0x06, 0x8a, 0x36, 0xa1, 0x6e, 0xb9,
0x26, 0x7e, 0x2c, 0x9c, 0xb2, 0xce, 0xf0, 0x68, 0x32, 0x95, 0x33, 0x44, 0x3b, 0x74, 0x2e, 0x53,
0x3a, 0x58, 0xe1, 0x27, 0xa1, 0x19, 0x29, 0xf4, 0x6d, 0x62, 0x7d, 0x8c, 0x3b, 0x0d, 0xae, 0x45,
0x01, 0xeb, 0x59, 0x1f, 0x63, 0x5a, 0x24, 0x5b, 0x2e, 0xc1, 0x7e, 0x10, 0xb6, 0x2c, 0x9d, 0x26,
0x4b, 0x5b, 0x4d, 0x0e, 0x15, 0xbe, 0xa4, 0xfd, 0xb6, 0x00, 0xad, 0x34, 0x22, 0xd4, 0x81, 0xca,
0x3e, 0x83, 0x84, 0xd6, 0x13, 0xfe, 0x52, 0xb4, 0xd8, 0x35, 0x06, 0x36, 0x8d, 0x79, 0x26, 0x7e,
0xcc, 0x8c, 0xa7, 0xaa, 0xd7, 0x39, 0x8c, 0x6d, 0x40, 0x8d, 0x80, 0xb3, 0xc7, 0x32, 0x65, 0x91,
0xa1, 0xac, 0x31, 0x08, 0xcb, 0x93, 0x1d, 0xa8, 0x70, 0x36, 0x42, 0xd3, 0x09, 0x7f, 0xe9, 0xc8,
0x60, 0x62, 0x31, 0xac, 0xdc, 0x74, 0xc2, 0x5f, 0xb4, 0x05, 0x0d, 0xbe, 0xe5, 0xd8, 0xf0, 0x0d,
0x27, 0x34, 0x9c, 0x17, 0xa5, 0xee, 0x7e, 0x0b, 0x1f, 0x7d, 0x48, 0xa3, 0xc7, 0x9e, 0x61, 0xf9,
0x3a, 0x17, 0xf4, 0x1e, 0x5b, 0x85, 0x56, 0x41, 0xe5, 0xbb, 0xec, 0x5b, 0x36, 0x16, 0x26, 0x58,
0x61, 0xc9, 0xb8, 0xc5, 0xe0, 0x37, 0x2d, 0x1b, 0x73, 0x2b, 0x8b, 0x58, 0x60, 0xa2, 0xad, 0x72,
0x23, 0x63, 0x10, 0x2a, 0x58, 0xed, 0xaf, 0x45, 0x58, 0xa2, 0xbe, 0x26, 0xdc, 0xee, 0x14, 0xd1,
0xe8, 0x22, 0x80, 0x49, 0x82, 0x7e, 0x2a, 0x22, 0xd5, 0x4c, 0x12, 0xec, 0xf2, 0xa0, 0xf4, 0x76,
0x18, 0x70, 0x8a, 0xf9, 0xb5, 0x6e, 0xc6, 0xf7, 0xa7, 0x93, 0xdb, 0x89, 0x4e, 0x02, 0x2e, 0x41,
0x93, 0x78, 0x13, 0x7f, 0x88, 0xfb, 0xa9, 0xae, 0xa4, 0xc1, 0x81, 0xbb, 0xf2, 0x98, 0xb9, 0x28,
0x3d, 0x91, 0x48, 0x44, 0xb7, 0xca, 0xe9, 0x12, 0x5c, 0x35, 0x9b, 0xe0, 0x6e, 0x41, 0x9b, 0xb9,
0x5f, 0x7f, 0xec, 0x11, 0xde, 0xdc, 0x09, 0xaf, 0xd5, 0x72, 0x9a, 0xfb, 0x3b, 0x64, 0xb4, 0x27,
0xa6, 0xea, 0x2d, 0xb6, 0x34, 0xfc, 0x25, 0xda, 0xcf, 0x0a, 0xb0, 0x2c, 0x9a, 0xc5, 0xd3, 0x2b,
0x36, 0x2f, 0xcd, 0x84, 0x51, 0xb3, 0xf8, 0x84, 0xf6, 0xab, 0x34, 0x47, 0x19, 0x54, 0x96, 0x94,
0x41, 0xe9, 0x16, 0x64, 0x71, 0xaa, 0x05, 0x89, 0x0e, 0x14, 0x2a, 0xc7, 0x38, 0x50, 0xf8, 0xa7,
0x02, 0xcd, 0x1e, 0x36, 0xfc, 0xe1, 0x41, 0x28, 0x8c, 0x37, 0x93, 0xa7, 0x28, 0x2f, 0xe5, 0x08,
0x3a, 0xb5, 0xe4, 0xcb, 0x73, 0x7c, 0xf2, 0x2f, 0x05, 0x1a, 0xdf, 0xa2, 0x43, 0x21, 0xb3, 0x6f,
0x25, 0x99, 0x7d, 0x39, 0x87, 0x59, 0x1d, 0x07, 0xbe, 0x85, 0x0f, 0xf1, 0x97, 0x8e, 0xdd, 0x3f,
0x2b, 0xd0, 0xed, 0x1d, 0xb9, 0x43, 0x9d, 0x7b, 0xd4, 0xe9, 0xcd, 0xfe, 0x12, 0x34, 0x0f, 0x53,
0x8d, 0x52, 0x81, 0x85, 0xff, 0xc6, 0x61, 0xb2, 0x53, 0xd2, 0x41, 0x0d, 0xeb, 0x21, 0xc1, 0x6c,
0x18, 0xe0, 0x5e, 0x91, 0x51, 0x9d, 0x21, 0x8e, 0x05, 0x88, 0xb6, 0x9f, 0x06, 0x6a, 0x3e, 0x2c,
0x49, 0xe6, 0xa1, 0xf3, 0x50, 0x11, 0x4d, 0x99, 0x48, 0x64, 0xdc, 0x0f, 0x4d, 0xaa, 0x9d, 0xf8,
0x58, 0xc1, 0x32, 0xa7, 0x8b, 0x20, 0x13, 0xbd, 0x00, 0xf5, 0xa8, 0x7a, 0x36, 0xa7, 0xd4, 0x63,
0x12, 0xed, 0x0f, 0x0a, 0x2c, 0xbf, 0x6f, 0xb8, 0xa6, 0xb7, 0xbf, 0x7f, 0x7a, 0xc9, 0x6d, 0x42,
0xaa, 0xb0, 0x9e, 0xb7, 0x65, 0x4f, 0x2d, 0x42, 0xaf, 0xc2, 0x19, 0x9f, 0x47, 0x30, 0x33, 0x2d,
0xda, 0xa2, 0xae, 0x86, 0x03, 0x91, 0xc8, 0x7e, 0x53, 0x00, 0x44, 0xa3, 0xee, 0x0d, 0xc3, 0x36,
0xdc, 0x21, 0x3e, 0x39, 0xe9, 0x97, 0xa1, 0x95, 0xca, 0x15, 0xd1, 0xcd, 0x46, 0x32, 0x59, 0x10,
0x74, 0x0b, 0x5a, 0x03, 0x8e, 0xaa, 0xef, 0x63, 0x83, 0x78, 0x2e, 0x0b, 0x82, 0x2d, 0x79, 0x77,
0x7e, 0xd7, 0xb7, 0x46, 0x23, 0xec, 0x6f, 0x7a, 0xae, 0xc9, 0xa3, 0x75, 0x73, 0x10, 0x92, 0x49,
0x97, 0x52, 0xe5, 0xc4, 0x89, 0x33, 0xec, 0x0a, 0x21, 0xca, 0x9c, 0x4c, 0x14, 0x04, 0x1b, 0x76,
0x2c, 0x88, 0x38, 0x6a, 0xaa, 0x7c, 0xa0, 0x97, 0x7f, 0x38, 0x23, 0x49, 0x64, 0xda, 0xef, 0x14,
0x40, 0x51, 0x7f, 0xc4, 0x3a, 0x12, 0x66, 0x61, 0xd9, 0xa5, 0x8a, 0x24, 0x78, 0x5f, 0x80, 0x9a,
0x19, 0xae, 0x14, 0x1e, 0x11, 0x03, 0xa8, 0xcf, 0x70, 0x36, 0xfa, 0x34, 0xeb, 0x61, 0x33, 0xac,
0xb6, 0x39, 0xf0, 0x36, 0x83, 0xa5, 0xf3, 0x60, 0x29, 0x9b, 0x07, 0x93, 0x67, 0x0f, 0xe5, 0xd4,
0xd9, 0x83, 0xf6, 0x69, 0x01, 0x54, 0x16, 0xd1, 0x36, 0xe3, 0xc6, 0x64, 0x2e, 0xa2, 0x2f, 0x41,
0x53, 0xdc, 0xfd, 0xa5, 0x08, 0x6f, 0x3c, 0x4c, 0x6c, 0x86, 0xae, 0xc2, 0x59, 0x3e, 0xc9, 0xc7,
0x64, 0x62, 0xc7, 0x85, 0x26, 0xaf, 0xfa, 0xd0, 0x43, 0x1e, 0x4a, 0xe9, 0x50, 0xb8, 0xe2, 0x1e,
0x2c, 0x8f, 0x6c, 0x6f, 0x60, 0xd8, 0xfd, 0xb4, 0x7a, 0x72, 0x9a, 0xaa, 0x69, 0x8b, 0x3f, 0xcb,
0x97, 0xf7, 0x92, 0x3a, 0x24, 0x68, 0x9b, 0xb6, 0xba, 0xf8, 0x41, 0x54, 0x08, 0x88, 0x63, 0xe5,
0x79, 0xea, 0x80, 0x06, 0x5d, 0x18, 0xfe, 0x69, 0x9f, 0x28, 0xd0, 0xce, 0x1c, 0x1f, 0x66, 0x1b,
0x26, 0x65, 0xba, 0x61, 0x7a, 0x0b, 0xca, 0xb4, 0x8b, 0xe0, 0xf1, 0xae, 0x25, 0x2f, 0xe6, 0xd3,
0xbb, 0xea, 0x7c, 0x01, 0xba, 0x02, 0x4b, 0x92, 0x8b, 0x26, 0x61, 0x03, 0x68, 0xfa, 0x9e, 0x49,
0xfb, 0x7d, 0x09, 0xea, 0x09, 0x79, 0xcc, 0xe8, 0xf5, 0xe6, 0x39, 0x0f, 0xca, 0xb0, 0x57, 0x9c,
0x66, 0x2f, 0xe7, 0xa6, 0x85, 0xda, 0x9d, 0x83, 0x1d, 0x5e, 0x25, 0x8b, 0x92, 0xdd, 0xc1, 0x0e,
0x6b, 0x3e, 0xa8, 0x49, 0x4e, 0x1c, 0xde, 0xa5, 0x71, 0x77, 0xaa, 0xb8, 0x13, 0x87, 0xf5, 0x68,
0xe9, 0x06, 0xa1, 0xf2, 0x84, 0x06, 0xa1, 0x9a, 0x6e, 0x10, 0x52, 0x7e, 0x54, 0xcb, 0xfa, 0xd1,
0xbc, 0xed, 0xd7, 0x55, 0x58, 0x1a, 0xfa, 0xd8, 0x08, 0xb0, 0x79, 0xe3, 0x68, 0x33, 0x1a, 0xea,
0xd4, 0x59, 0x5e, 0x95, 0x0d, 0xa1, 0x9b, 0xf1, 0x39, 0x0a, 0xd7, 0x72, 0x83, 0x69, 0x59, 0xde,
0x7f, 0x08, 0xdd, 0x70, 0x25, 0x87, 0xe1, 0x99, 0xfd, 0x65, 0x1b, 0xbf, 0xe6, 0x89, 0x1a, 0xbf,
0x17, 0xa0, 0x1e, 0x9f, 0x26, 0x90, 0x4e, 0x8b, 0x47, 0xbe, 0xe8, 0x38, 0x81, 0xa4, 0x82, 0x41,
0x3b, 0x1d, 0x0c, 0xfe, 0x52, 0x84, 0x56, 0x5c, 0xf2, 0xcf, 0x1d, 0x0a, 0xe6, 0xb9, 0x30, 0xdd,
0x05, 0x35, 0x4e, 0xa8, 0x4c, 0x4a, 0x4f, 0xec, 0x5a, 0xb2, 0x27, 0xf4, 0xed, 0x71, 0xc6, 0xe7,
0x52, 0x67, 0xa0, 0xa5, 0x63, 0x9d, 0x81, 0x9e, 0xf2, 0x6e, 0xe9, 0x1a, 0x9c, 0x8b, 0x92, 0x68,
0x8a, 0x6d, 0x5e, 0x51, 0x9f, 0x0d, 0x07, 0xf7, 0x92, 0xec, 0xe7, 0xb8, 0x71, 0x25, 0xcf, 0x8d,
0xb3, 0x6a, 0xac, 0x4e, 0xa9, 0x71, 0xfa, 0x8a, 0xab, 0x26, 0xbb, 0xe2, 0xba, 0x07, 0x4b, 0xf7,
0x5c, 0x32, 0x19, 0x90, 0xa1, 0x6f, 0x0d, 0x70, 0x54, 0x5a, 0xce, 0xa3, 0xd6, 0x2e, 0x54, 0x33,
0xd5, 0x69, 0xf4, 0xaf, 0xfd, 0x50, 0x81, 0xe5, 0xe9, 0x7d, 0x99, 0xc5, 0xc4, 0xc1, 0x40, 0x49,
0x05, 0x83, 0xef, 0xc0, 0x52, 0xbc, 0x7d, 0xba, 0xee, 0xcd, 0xa9, 0xec, 0x24, 0x84, 0xeb, 0x28,
0xde, 0x23, 0x84, 0x69, 0xff, 0x56, 0xa2, 0x53, 0x46, 0x0a, 0x1b, 0xb1, 0xb3, 0x53, 0x9a, 0xa0,
0x3c, 0xd7, 0xb6, 0xdc, 0xa8, 0x45, 0x15, 0x3c, 0x72, 0xa0, 0x68, 0x51, 0xdf, 0x87, 0xb6, 0x98,
0x14, 0xe5, 0x99, 0x39, 0x2b, 0xab, 0x16, 0x5f, 0x17, 0x65, 0x98, 0xcb, 0xd0, 0xf2, 0xf6, 0xf7,
0x93, 0xf8, 0x78, 0xa0, 0x6c, 0x0a, 0xa8, 0x40, 0xf8, 0x4d, 0x50, 0xc3, 0x69, 0xc7, 0xcd, 0x6c,
0x6d, 0xb1, 0x30, 0xaa, 0xd0, 0x7e, 0xa0, 0x40, 0x27, 0x9d, 0xe7, 0x12, 0xec, 0x1f, 0xbf, 0x4e,
0xfb, 0x7a, 0xfa, 0x3a, 0xe8, 0xf2, 0x13, 0xe8, 0x89, 0xf1, 0x88, 0xf3, 0x84, 0xb5, 0x6f, 0x40,
0x2d, 0x6a, 0x1f, 0x50, 0x1d, 0x2a, 0xf7, 0xdc, 0x5b, 0xae, 0xf7, 0xc8, 0x55, 0x17, 0x50, 0x05,
0x8a, 0xd7, 0x6d, 0x5b, 0x55, 0x50, 0x13, 0x6a, 0xbd, 0xc0, 0xc7, 0x86, 0x63, 0xb9, 0x23, 0xb5,
0x80, 0x5a, 0x00, 0xef, 0x5b, 0x24, 0xf0, 0x7c, 0x6b, 0x68, 0xd8, 0x6a, 0x71, 0xed, 0x63, 0x68,
0xa5, 0xbd, 0x1e, 0x35, 0xa0, 0xba, 0xeb, 0x05, 0xef, 0x3d, 0xb6, 0x48, 0xa0, 0x2e, 0xd0, 0xf9,
0xbb, 0x5e, 0xb0, 0xe7, 0x63, 0x82, 0xdd, 0x40, 0x55, 0x10, 0xc0, 0xe2, 0x07, 0xee, 0x96, 0x45,
0x1e, 0xa8, 0x05, 0xb4, 0x24, 0x92, 0xb2, 0x61, 0xef, 0x08, 0x57, 0x52, 0x8b, 0x74, 0x79, 0xf4,
0x57, 0x42, 0x2a, 0x34, 0xa2, 0x29, 0xdb, 0x7b, 0xf7, 0xd4, 0x32, 0xaa, 0x41, 0x99, 0x7f, 0x2e,
0xae, 0x99, 0xa0, 0x66, 0x2b, 0x4a, 0xba, 0x27, 0x67, 0x22, 0x02, 0xa9, 0x0b, 0x94, 0x33, 0x51,
0xd2, 0xab, 0x0a, 0x6a, 0x43, 0x3d, 0x51, 0x20, 0xab, 0x05, 0x0a, 0xd8, 0xf6, 0xc7, 0x43, 0x51,
0x2a, 0x73, 0x12, 0xa8, 0xde, 0xb7, 0xa8, 0x24, 0x4a, 0x6b, 0x37, 0xa0, 0x1a, 0x86, 0x23, 0x3a,
0x55, 0x88, 0x88, 0xfe, 0xaa, 0x0b, 0xe8, 0x0c, 0x34, 0x53, 0x17, 0xf3, 0xaa, 0x82, 0x10, 0xb4,
0xd2, 0x0f, 0x46, 0xd4, 0xc2, 0xc6, 0x2f, 0x1a, 0x00, 0xbc, 0x5e, 0xf3, 0x3c, 0xdf, 0x44, 0x63,
0x40, 0xdb, 0x38, 0xa0, 0xb9, 0xc8, 0x73, 0xc3, 0x3c, 0x42, 0xd0, 0xd5, 0xfc, 0xb7, 0x0b, 0x99,
0xa9, 0x82, 0xd4, 0x6e, 0x5e, 0xeb, 0x9a, 0x99, 0xae, 0x2d, 0x20, 0x87, 0x61, 0xbc, 0x6b, 0x39,
0xf8, 0xae, 0x35, 0x7c, 0x10, 0x15, 0x7a, 0xf9, 0x18, 0x33, 0x53, 0x43, 0x8c, 0x99, 0xb0, 0x2f,
0x7e, 0x7a, 0x81, 0x6f, 0xb9, 0xa3, 0xf0, 0x7a, 0x4f, 0x5b, 0x40, 0x0f, 0x33, 0x6f, 0x35, 0x42,
0x84, 0x1b, 0xf3, 0x3c, 0xcf, 0x38, 0x19, 0x4a, 0x1b, 0xda, 0x99, 0x87, 0x5d, 0x68, 0x4d, 0x7e,
0x43, 0x28, 0x7b, 0x84, 0xd6, 0x7d, 0x75, 0xae, 0xb9, 0x11, 0x36, 0x0b, 0x5a, 0xe9, 0xc7, 0x4b,
0xe8, 0xff, 0xf3, 0x36, 0x98, 0x7a, 0xa3, 0xd0, 0x5d, 0x9b, 0x67, 0x6a, 0x84, 0xea, 0x3e, 0xb7,
0xa7, 0x59, 0xa8, 0xa4, 0xef, 0x43, 0xba, 0x4f, 0xba, 0x59, 0xd5, 0x16, 0xd0, 0x77, 0xe1, 0xcc,
0xd4, 0x4b, 0x0a, 0xf4, 0x9a, 0xbc, 0x5f, 0x97, 0x3f, 0xb8, 0x98, 0x85, 0xe1, 0x7e, 0xd6, 0x1b,
0xf2, 0xa9, 0x9f, 0x7a, 0x75, 0x34, 0x3f, 0xf5, 0x89, 0xed, 0x9f, 0x44, 0xfd, 0xb1, 0x31, 0x4c,
0x98, 0xdb, 0x64, 0x3b, 0x87, 0xd7, 0x65, 0x28, 0x72, 0x9f, 0x73, 0x74, 0xd7, 0xe7, 0x9d, 0x9e,
0xb4, 0xae, 0xf4, 0x8b, 0x01, 0xb9, 0xd0, 0xa4, 0xaf, 0x1c, 0xe4, 0xd6, 0x25, 0x7f, 0x80, 0xa0,
0x2d, 0xa0, 0xbb, 0xa9, 0x68, 0x88, 0x5e, 0xce, 0x53, 0x4e, 0xfa, 0x3c, 0x61, 0x96, 0xdc, 0xfa,
0x00, 0xdb, 0x38, 0xb8, 0x83, 0x03, 0xdf, 0x1a, 0x92, 0xec, 0xa6, 0xe2, 0x27, 0x9e, 0x10, 0x6e,
0xfa, 0xca, 0xcc, 0x79, 0x11, 0xd9, 0x03, 0xa8, 0x6f, 0xe3, 0x40, 0x1c, 0x0e, 0x11, 0x94, 0xbb,
0x32, 0x9c, 0x11, 0xa2, 0x58, 0x9d, 0x3d, 0x31, 0x19, 0x51, 0x32, 0x0f, 0x18, 0x50, 0xae, 0x6c,
0xa7, 0x9f, 0x55, 0xc8, 0x23, 0x4a, 0xce, 0x8b, 0x08, 0x6d, 0x61, 0xe3, 0xef, 0x75, 0xa8, 0xb1,
0x14, 0x41, 0x53, 0xcf, 0xff, 0x32, 0xc4, 0x53, 0xc8, 0x10, 0x1f, 0x41, 0x3b, 0x73, 0x1f, 0x2e,
0xd7, 0xa7, 0xfc, 0xd2, 0x7c, 0x96, 0xc9, 0x0f, 0x00, 0x4d, 0xdf, 0x68, 0xcb, 0x43, 0x45, 0xee,
0xcd, 0xf7, 0x2c, 0x1c, 0x1f, 0xf2, 0x27, 0x25, 0x51, 0xf5, 0xfa, 0x4a, 0x9e, 0xb7, 0x66, 0x4e,
0x2e, 0xbf, 0xf8, 0x40, 0xfa, 0xf4, 0x13, 0xcd, 0x47, 0xd0, 0xce, 0xdc, 0xf3, 0xc8, 0xb5, 0x2b,
0xbf, 0x0c, 0x9a, 0xb5, 0xfb, 0xe7, 0x18, 0x91, 0x4d, 0x58, 0x92, 0x9c, 0xde, 0x23, 0x69, 0x16,
0xc9, 0x3f, 0xe6, 0x9f, 0xcd, 0x50, 0x33, 0xe5, 0x52, 0x68, 0x35, 0x8f, 0xc8, 0xec, 0xb3, 0xd9,
0xee, 0x6b, 0xf3, 0xbd, 0xb1, 0x8d, 0x18, 0xea, 0xc1, 0x22, 0xbf, 0x38, 0x42, 0x2f, 0xca, 0x9b,
0x93, 0xc4, 0xa5, 0x52, 0x77, 0xd6, 0xd5, 0x13, 0x99, 0xd8, 0x01, 0x61, 0x9b, 0x96, 0x59, 0xb4,
0x44, 0xd2, 0x7b, 0xc7, 0xe4, 0x6d, 0x4f, 0x77, 0xf6, 0x05, 0x4f, 0xb8, 0xe9, 0xd3, 0x4e, 0x5b,
0x37, 0xde, 0xb8, 0xbf, 0x31, 0xb2, 0x82, 0x83, 0xc9, 0x80, 0xea, 0xe3, 0x0a, 0x9f, 0xf9, 0xba,
0xe5, 0x89, 0xaf, 0x2b, 0x21, 0x69, 0x57, 0xd8, 0x4e, 0x57, 0x18, 0x2f, 0xe3, 0xc1, 0x60, 0x91,
0xfd, 0x5e, 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x62, 0xc3, 0x9a, 0xa7, 0xb7, 0x31, 0x00,
0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -3593,6 +3669,7 @@ type QueryNodeClient interface {
ReleaseSegments(ctx context.Context, in *ReleaseSegmentsRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
GetSegmentInfo(ctx context.Context, in *GetSegmentInfoRequest, opts ...grpc.CallOption) (*GetSegmentInfoResponse, error)
SyncReplicaSegments(ctx context.Context, in *SyncReplicaSegmentsRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
GetStatistics(ctx context.Context, in *GetStatisticsRequest, opts ...grpc.CallOption) (*internalpb.GetStatisticsResponse, error)
Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*internalpb.SearchResults, error)
Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*internalpb.RetrieveResults, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+8+--+Add+metrics+for+proxy
@ -3706,6 +3783,15 @@ func (c *queryNodeClient) SyncReplicaSegments(ctx context.Context, in *SyncRepli
return out, nil
}
func (c *queryNodeClient) GetStatistics(ctx context.Context, in *GetStatisticsRequest, opts ...grpc.CallOption) (*internalpb.GetStatisticsResponse, error) {
out := new(internalpb.GetStatisticsResponse)
err := c.cc.Invoke(ctx, "/milvus.proto.query.QueryNode/GetStatistics", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryNodeClient) Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*internalpb.SearchResults, error) {
out := new(internalpb.SearchResults)
err := c.cc.Invoke(ctx, "/milvus.proto.query.QueryNode/Search", in, out, opts...)
@ -3746,6 +3832,7 @@ type QueryNodeServer interface {
ReleaseSegments(context.Context, *ReleaseSegmentsRequest) (*commonpb.Status, error)
GetSegmentInfo(context.Context, *GetSegmentInfoRequest) (*GetSegmentInfoResponse, error)
SyncReplicaSegments(context.Context, *SyncReplicaSegmentsRequest) (*commonpb.Status, error)
GetStatistics(context.Context, *GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error)
Search(context.Context, *SearchRequest) (*internalpb.SearchResults, error)
Query(context.Context, *QueryRequest) (*internalpb.RetrieveResults, error)
// https://wiki.lfaidata.foundation/display/MIL/MEP+8+--+Add+metrics+for+proxy
@ -3789,6 +3876,9 @@ func (*UnimplementedQueryNodeServer) GetSegmentInfo(ctx context.Context, req *Ge
func (*UnimplementedQueryNodeServer) SyncReplicaSegments(ctx context.Context, req *SyncReplicaSegmentsRequest) (*commonpb.Status, error) {
return nil, status.Errorf(codes.Unimplemented, "method SyncReplicaSegments not implemented")
}
func (*UnimplementedQueryNodeServer) GetStatistics(ctx context.Context, req *GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetStatistics not implemented")
}
func (*UnimplementedQueryNodeServer) Search(ctx context.Context, req *SearchRequest) (*internalpb.SearchResults, error) {
return nil, status.Errorf(codes.Unimplemented, "method Search not implemented")
}
@ -4001,6 +4091,24 @@ func _QueryNode_SyncReplicaSegments_Handler(srv interface{}, ctx context.Context
return interceptor(ctx, in, info, handler)
}
func _QueryNode_GetStatistics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetStatisticsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryNodeServer).GetStatistics(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/milvus.proto.query.QueryNode/GetStatistics",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryNodeServer).GetStatistics(ctx, req.(*GetStatisticsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _QueryNode_Search_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SearchRequest)
if err := dec(in); err != nil {
@ -4103,6 +4211,10 @@ var _QueryNode_serviceDesc = grpc.ServiceDesc{
MethodName: "SyncReplicaSegments",
Handler: _QueryNode_SyncReplicaSegments_Handler,
},
{
MethodName: "GetStatistics",
Handler: _QueryNode_GetStatistics_Handler,
},
{
MethodName: "Search",
Handler: _QueryNode_Search_Handler,

View File

@ -711,6 +711,115 @@ func (node *Proxy) DescribeCollection(ctx context.Context, request *milvuspb.Des
return dct.result, nil
}
// GetStatistics get the statistics, such as `num_rows`.
// WARNING: It is an experimental API
func (node *Proxy) GetStatistics(ctx context.Context, request *milvuspb.GetStatisticsRequest) (*milvuspb.GetStatisticsResponse, error) {
if !node.checkHealthy() {
return &milvuspb.GetStatisticsResponse{
Status: unhealthyStatus(),
}, nil
}
sp, ctx := trace.StartSpanFromContextWithOperationName(ctx, "Proxy-GetCollectionStatistics")
defer sp.Finish()
traceID, _, _ := trace.InfoFromSpan(sp)
method := "GetStatistics"
tr := timerecord.NewTimeRecorder(method)
g := &getStatisticsTask{
request: request,
Condition: NewTaskCondition(ctx),
ctx: ctx,
tr: tr,
dc: node.dataCoord,
qc: node.queryCoord,
shardMgr: node.shardMgr,
}
log.Debug(
rpcReceived(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName),
zap.Strings("partitions", request.PartitionNames))
if err := node.sched.ddQueue.Enqueue(g); err != nil {
log.Warn(
rpcFailedToEnqueue(method),
zap.Error(err),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName),
zap.Strings("partitions", request.PartitionNames))
metrics.ProxyDQLFunctionCall.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method,
metrics.AbandonLabel).Inc()
return &milvuspb.GetStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
},
}, nil
}
log.Debug(
rpcEnqueued(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.Int64("msgID", g.ID()),
zap.Uint64("BeginTS", g.BeginTs()),
zap.Uint64("EndTS", g.EndTs()),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName),
zap.Strings("partitions", request.PartitionNames))
if err := g.WaitToFinish(); err != nil {
log.Warn(
rpcFailedToWaitToFinish(method),
zap.Error(err),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.Int64("MsgID", g.ID()),
zap.Uint64("BeginTS", g.BeginTs()),
zap.Uint64("EndTS", g.EndTs()),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName),
zap.Strings("partitions", request.PartitionNames))
metrics.ProxyDQLFunctionCall.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method,
metrics.TotalLabel).Inc()
metrics.ProxyDQLFunctionCall.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method,
metrics.FailLabel).Inc()
return &milvuspb.GetStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
Reason: err.Error(),
},
}, nil
}
log.Debug(
rpcDone(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.Int64("msgID", g.ID()),
zap.Uint64("BeginTS", g.BeginTs()),
zap.Uint64("EndTS", g.EndTs()),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName))
metrics.ProxyDQLFunctionCall.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method,
metrics.TotalLabel).Inc()
metrics.ProxyDQLFunctionCall.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method,
metrics.SuccessLabel).Inc()
metrics.ProxyDQLReqLatency.WithLabelValues(strconv.FormatInt(Params.ProxyCfg.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds()))
return g.result, nil
}
// GetCollectionStatistics get the collection statistics, such as `num_rows`.
func (node *Proxy) GetCollectionStatistics(ctx context.Context, request *milvuspb.GetCollectionStatisticsRequest) (*milvuspb.GetCollectionStatisticsResponse, error) {
if !node.checkHealthy() {
@ -732,14 +841,16 @@ func (node *Proxy) GetCollectionStatistics(ctx context.Context, request *milvusp
dataCoord: node.dataCoord,
}
log.Debug("GetCollectionStatistics received",
log.Debug(
rpcReceived(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName))
if err := node.sched.ddQueue.Enqueue(g); err != nil {
log.Warn("GetCollectionStatistics failed to enqueue",
log.Warn(
rpcFailedToEnqueue(method),
zap.Error(err),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
@ -757,17 +868,19 @@ func (node *Proxy) GetCollectionStatistics(ctx context.Context, request *milvusp
}, nil
}
log.Debug("GetCollectionStatistics enqueued",
log.Debug(
rpcEnqueued(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.Int64("MsgID", g.ID()),
zap.Int64("msgID", g.ID()),
zap.Uint64("BeginTS", g.BeginTs()),
zap.Uint64("EndTS", g.EndTs()),
zap.String("db", request.DbName),
zap.String("collection", request.CollectionName))
if err := g.WaitToFinish(); err != nil {
log.Warn("GetCollectionStatistics failed to WaitToFinish",
log.Warn(
rpcFailedToWaitToFinish(method),
zap.Error(err),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
@ -790,10 +903,11 @@ func (node *Proxy) GetCollectionStatistics(ctx context.Context, request *milvusp
}, nil
}
log.Debug("GetCollectionStatistics done",
log.Debug(
rpcDone(method),
zap.String("traceID", traceID),
zap.String("role", typeutil.ProxyRole),
zap.Int64("MsgID", g.ID()),
zap.Int64("msgID", g.ID()),
zap.Uint64("BeginTS", g.BeginTs()),
zap.Uint64("EndTS", g.EndTs()),
zap.String("db", request.DbName),
@ -1409,6 +1523,8 @@ func (node *Proxy) GetPartitionStatistics(ctx context.Context, request *milvuspb
sp, ctx := trace.StartSpanFromContextWithOperationName(ctx, "Proxy-GetPartitionStatistics")
defer sp.Finish()
traceID, _, _ := trace.InfoFromSpan(sp)
method := "GetPartitionStatistics"
tr := timerecord.NewTimeRecorder(method)
g := &getPartitionStatisticsTask{
ctx: ctx,
@ -1417,9 +1533,6 @@ func (node *Proxy) GetPartitionStatistics(ctx context.Context, request *milvuspb
dataCoord: node.dataCoord,
}
method := "GetPartitionStatistics"
tr := timerecord.NewTimeRecorder(method)
log.Debug(
rpcReceived(method),
zap.String("traceID", traceID),

View File

@ -651,7 +651,7 @@ func TestProxy(t *testing.T) {
}
createCollectionReq := constructCreateCollectionRequest()
constructInsertRequest := func() *milvuspb.InsertRequest {
constructCollectionInsertRequest := func() *milvuspb.InsertRequest {
fVecColumn := newFloatVectorFieldData(floatVecField, rowNum, dim)
hashKeys := generateHashKeys(rowNum)
return &milvuspb.InsertRequest{
@ -665,6 +665,20 @@ func TestProxy(t *testing.T) {
}
}
constructPartitionInsertRequest := func() *milvuspb.InsertRequest {
fVecColumn := newFloatVectorFieldData(floatVecField, rowNum, dim)
hashKeys := generateHashKeys(rowNum)
return &milvuspb.InsertRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
PartitionName: partitionName,
FieldsData: []*schemapb.FieldData{fVecColumn},
HashKeys: hashKeys,
NumRows: uint32(rowNum),
}
}
constructCreateIndexRequest := func() *milvuspb.CreateIndexRequest {
return &milvuspb.CreateIndexRequest{
Base: nil,
@ -1055,7 +1069,7 @@ func TestProxy(t *testing.T) {
wg.Add(1)
t.Run("insert", func(t *testing.T) {
defer wg.Done()
req := constructInsertRequest()
req := constructCollectionInsertRequest()
resp, err := proxy.Insert(ctx, req)
assert.NoError(t, err)
@ -1067,7 +1081,7 @@ func TestProxy(t *testing.T) {
// TODO(dragondriver): proxy.Delete()
flushed := true // fortunately, no task depends on this state, maybe CreateIndex?
flushed := true
wg.Add(1)
t.Run("flush", func(t *testing.T) {
defer wg.Done()
@ -1094,7 +1108,7 @@ func TestProxy(t *testing.T) {
// waiting for flush operation to be done
counter := 0
for !f() {
if counter > 10 {
if counter > 100 {
flushed = false
break
}
@ -1107,6 +1121,32 @@ func TestProxy(t *testing.T) {
log.Warn("flush operation was not sure to be done")
}
wg.Add(1)
t.Run("get statistics after flush", func(t *testing.T) {
defer wg.Done()
if !flushed {
t.Skip("flush operation was not done")
}
resp, err := proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
})
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
rowNumStr := funcutil.KeyValuePair2Map(resp.Stats)["row_count"]
assert.Equal(t, strconv.Itoa(rowNum), rowNumStr)
// get statistics of other collection -> fail
resp, err = proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: otherCollectionName,
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
wg.Add(1)
t.Run("create index", func(t *testing.T) {
defer wg.Done()
@ -1242,7 +1282,7 @@ func TestProxy(t *testing.T) {
assert.Equal(t, 1, len(resp.CollectionNames))
assert.Equal(t, 1, len(resp.InMemoryPercentages))
// get in-memory percentage of not loaded collection -> fail
// get in-memory percentage of not loaded collection -> fail
resp, err = proxy.ShowCollections(ctx, &milvuspb.ShowCollectionsRequest{
Base: nil,
DbName: dbName,
@ -1268,6 +1308,33 @@ func TestProxy(t *testing.T) {
assert.Equal(t, 1, len(resp.Replicas))
})
wg.Add(1)
t.Run("get collection statistics from shard", func(t *testing.T) {
defer wg.Done()
if !loaded {
t.Skip("collection not loaded")
return
}
resp, err := proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
})
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
rowNumStr := funcutil.KeyValuePair2Map(resp.Stats)["row_count"]
assert.Equal(t, strconv.Itoa(rowNum), rowNumStr)
// get statistics of other collection -> fail
resp, err = proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: otherCollectionName,
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
// nprobe := 10
// topk := 10
// roundDecimal := 6
@ -1659,9 +1726,13 @@ func TestProxy(t *testing.T) {
assert.Equal(t, 0, len(resp.CollectionNames))
})
pLoaded := true
wg.Add(1)
t.Run("load partitions", func(t *testing.T) {
defer wg.Done()
collectionID, err := globalMetaCache.GetCollectionID(ctx, collectionName)
assert.NoError(t, err)
resp, err := proxy.LoadPartitions(ctx, &milvuspb.LoadPartitionsRequest{
Base: nil,
DbName: dbName,
@ -1693,7 +1764,41 @@ func TestProxy(t *testing.T) {
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
f := func() bool {
resp, err := proxy.ShowPartitions(ctx, &milvuspb.ShowPartitionsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
CollectionID: collectionID,
PartitionNames: []string{partitionName},
Type: milvuspb.ShowType_InMemory,
})
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
for idx, name := range resp.PartitionNames {
if name == partitionName && resp.InMemoryPercentages[idx] == 100 {
return true
}
}
return false
}
// waiting for collection to be loaded
counter := 0
for !f() {
if counter > 100 {
pLoaded = false
break
}
// avoid too frequent rpc call
time.Sleep(100 * time.Millisecond)
counter++
}
})
assert.True(t, pLoaded)
wg.Add(1)
t.Run("show in-memory partitions", func(t *testing.T) {
@ -1739,6 +1844,86 @@ func TestProxy(t *testing.T) {
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
wg.Add(1)
t.Run("insert partition", func(t *testing.T) {
defer wg.Done()
req := constructPartitionInsertRequest()
resp, err := proxy.Insert(ctx, req)
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
assert.Equal(t, rowNum, len(resp.SuccIndex))
assert.Equal(t, 0, len(resp.ErrIndex))
assert.Equal(t, int64(rowNum), resp.InsertCnt)
})
wg.Add(1)
t.Run("get partition statistics from shard", func(t *testing.T) {
defer wg.Done()
if !pLoaded {
t.Skip("partition not loaded")
}
resp, err := proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
PartitionNames: []string{partitionName},
})
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
rowNumStr := funcutil.KeyValuePair2Map(resp.Stats)["row_count"]
assert.Equal(t, strconv.Itoa(rowNum), rowNumStr)
// non-exist partition -> fail
resp, err = proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
PartitionNames: []string{otherPartitionName},
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
// non-exist collection -> fail
resp, err = proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: otherCollectionName,
PartitionNames: []string{partitionName},
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
wg.Add(1)
t.Run("get collection statistics from hybrid", func(t *testing.T) {
defer wg.Done()
if !flushed {
t.Skip("flush operation was not done")
}
if !pLoaded {
t.Skip("partition not loaded")
}
resp, err := proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: collectionName,
})
assert.NoError(t, err)
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
rowNumStr := funcutil.KeyValuePair2Map(resp.Stats)["row_count"]
assert.Equal(t, strconv.Itoa(rowNum*2), rowNumStr)
// get statistics of other collection -> fail
resp, err = proxy.GetStatistics(ctx, &milvuspb.GetStatisticsRequest{
Base: nil,
DbName: dbName,
CollectionName: otherCollectionName,
})
assert.NoError(t, err)
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
})
wg.Add(1)
t.Run("release partition", func(t *testing.T) {
defer wg.Done()
@ -3165,3 +3350,7 @@ func TestProxy_ListImportTasks(t *testing.T) {
assert.Nil(t, err)
})
}
func TestProxy_GetStatistics(t *testing.T) {
}

View File

@ -37,10 +37,19 @@ type QueryNodeMock struct {
state atomic.Value // internal.StateCode
withSearchResult *internalpb.SearchResults
withQueryResult *internalpb.RetrieveResults
queryError error
searchError error
withStatisticsResponse *internalpb.GetStatisticsResponse
withSearchResult *internalpb.SearchResults
withQueryResult *internalpb.RetrieveResults
queryError error
searchError error
statisticsError error
}
func (m *QueryNodeMock) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
if m.statisticsError != nil {
return nil, m.statisticsError
}
return m.withStatisticsResponse, nil
}
func (m *QueryNodeMock) Search(ctx context.Context, req *querypb.SearchRequest) (*internalpb.SearchResults, error) {

View File

@ -570,191 +570,6 @@ func (dct *describeCollectionTask) PostExecute(ctx context.Context) error {
return nil
}
type getCollectionStatisticsTask struct {
Condition
*milvuspb.GetCollectionStatisticsRequest
ctx context.Context
dataCoord types.DataCoord
result *milvuspb.GetCollectionStatisticsResponse
collectionID UniqueID
}
func (g *getCollectionStatisticsTask) TraceCtx() context.Context {
return g.ctx
}
func (g *getCollectionStatisticsTask) ID() UniqueID {
return g.Base.MsgID
}
func (g *getCollectionStatisticsTask) SetID(uid UniqueID) {
g.Base.MsgID = uid
}
func (g *getCollectionStatisticsTask) Name() string {
return GetCollectionStatisticsTaskName
}
func (g *getCollectionStatisticsTask) Type() commonpb.MsgType {
return g.Base.MsgType
}
func (g *getCollectionStatisticsTask) BeginTs() Timestamp {
return g.Base.Timestamp
}
func (g *getCollectionStatisticsTask) EndTs() Timestamp {
return g.Base.Timestamp
}
func (g *getCollectionStatisticsTask) SetTs(ts Timestamp) {
g.Base.Timestamp = ts
}
func (g *getCollectionStatisticsTask) OnEnqueue() error {
g.Base = &commonpb.MsgBase{}
return nil
}
func (g *getCollectionStatisticsTask) PreExecute(ctx context.Context) error {
g.Base.MsgType = commonpb.MsgType_GetCollectionStatistics
g.Base.SourceID = Params.ProxyCfg.GetNodeID()
return nil
}
func (g *getCollectionStatisticsTask) Execute(ctx context.Context) error {
collID, err := globalMetaCache.GetCollectionID(ctx, g.CollectionName)
if err != nil {
return err
}
g.collectionID = collID
req := &datapb.GetCollectionStatisticsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetCollectionStatistics,
MsgID: g.Base.MsgID,
Timestamp: g.Base.Timestamp,
SourceID: g.Base.SourceID,
},
CollectionID: collID,
}
result, _ := g.dataCoord.GetCollectionStatistics(ctx, req)
if result == nil {
return errors.New("get collection statistics resp is nil")
}
if result.Status.ErrorCode != commonpb.ErrorCode_Success {
return errors.New(result.Status.Reason)
}
g.result = &milvuspb.GetCollectionStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
},
Stats: result.Stats,
}
return nil
}
func (g *getCollectionStatisticsTask) PostExecute(ctx context.Context) error {
return nil
}
type getPartitionStatisticsTask struct {
Condition
*milvuspb.GetPartitionStatisticsRequest
ctx context.Context
dataCoord types.DataCoord
result *milvuspb.GetPartitionStatisticsResponse
collectionID UniqueID
}
func (g *getPartitionStatisticsTask) TraceCtx() context.Context {
return g.ctx
}
func (g *getPartitionStatisticsTask) ID() UniqueID {
return g.Base.MsgID
}
func (g *getPartitionStatisticsTask) SetID(uid UniqueID) {
g.Base.MsgID = uid
}
func (g *getPartitionStatisticsTask) Name() string {
return GetPartitionStatisticsTaskName
}
func (g *getPartitionStatisticsTask) Type() commonpb.MsgType {
return g.Base.MsgType
}
func (g *getPartitionStatisticsTask) BeginTs() Timestamp {
return g.Base.Timestamp
}
func (g *getPartitionStatisticsTask) EndTs() Timestamp {
return g.Base.Timestamp
}
func (g *getPartitionStatisticsTask) SetTs(ts Timestamp) {
g.Base.Timestamp = ts
}
func (g *getPartitionStatisticsTask) OnEnqueue() error {
g.Base = &commonpb.MsgBase{}
return nil
}
func (g *getPartitionStatisticsTask) PreExecute(ctx context.Context) error {
g.Base.MsgType = commonpb.MsgType_GetPartitionStatistics
g.Base.SourceID = Params.ProxyCfg.GetNodeID()
return nil
}
func (g *getPartitionStatisticsTask) Execute(ctx context.Context) error {
collID, err := globalMetaCache.GetCollectionID(ctx, g.CollectionName)
if err != nil {
return err
}
g.collectionID = collID
partitionID, err := globalMetaCache.GetPartitionID(ctx, g.CollectionName, g.PartitionName)
if err != nil {
return err
}
req := &datapb.GetPartitionStatisticsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetPartitionStatistics,
MsgID: g.Base.MsgID,
Timestamp: g.Base.Timestamp,
SourceID: g.Base.SourceID,
},
CollectionID: collID,
PartitionID: partitionID,
}
result, _ := g.dataCoord.GetPartitionStatistics(ctx, req)
if result == nil {
return errors.New("get partition statistics resp is nil")
}
if result.Status.ErrorCode != commonpb.ErrorCode_Success {
return errors.New(result.Status.Reason)
}
g.result = &milvuspb.GetPartitionStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
},
Stats: result.Stats,
}
return nil
}
func (g *getPartitionStatisticsTask) PostExecute(ctx context.Context) error {
return nil
}
type showCollectionsTask struct {
Condition
*milvuspb.ShowCollectionsRequest

View File

@ -284,7 +284,7 @@ func (t *queryTask) PostExecute(ctx context.Context) error {
log.Info("Query result is nil", zap.Int64("msgID", t.ID()), zap.Any("requestType", "query"))
t.result.Status = &commonpb.Status{
ErrorCode: commonpb.ErrorCode_EmptyCollection,
Reason: "emptly collection", // TODO
Reason: "empty collection", // TODO
}
return nil
}

View File

@ -0,0 +1,766 @@
package proxy
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/milvus-io/milvus/internal/proto/datapb"
"github.com/milvus-io/milvus/internal/proto/milvuspb"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/proto/querypb"
"github.com/milvus-io/milvus/internal/types"
"github.com/milvus-io/milvus/internal/util/funcutil"
"github.com/milvus-io/milvus/internal/util/grpcclient"
"github.com/milvus-io/milvus/internal/util/timerecord"
"github.com/milvus-io/milvus/internal/util/trace"
"github.com/milvus-io/milvus/internal/util/tsoutil"
"go.uber.org/zap"
)
type getStatisticsTask struct {
request *milvuspb.GetStatisticsRequest
result *milvuspb.GetStatisticsResponse
Condition
collectionName string
partitionNames []string
// partition ids that are loaded into query node, require get statistics from QueryNode
loadedPartitionIDs []UniqueID
// partition ids that are not loaded into query node, require get statistics from DataCoord
unloadedPartitionIDs []UniqueID
ctx context.Context
dc types.DataCoord
tr *timerecord.TimeRecorder
toReduceResults []*internalpb.GetStatisticsResponse
fromDataCoord bool
fromQueryNode bool
// if query from shard
*internalpb.GetStatisticsRequest
qc types.QueryCoord
resultBuf chan *internalpb.GetStatisticsResponse
statisticShardPolicy pickShardPolicy
shardMgr *shardClientMgr
}
func (g *getStatisticsTask) TraceCtx() context.Context {
return g.ctx
}
func (g *getStatisticsTask) ID() UniqueID {
return g.Base.MsgID
}
func (g *getStatisticsTask) SetID(uid UniqueID) {
g.Base.MsgID = uid
}
func (g *getStatisticsTask) Name() string {
return GetPartitionStatisticsTaskName
}
func (g *getStatisticsTask) Type() commonpb.MsgType {
return g.Base.MsgType
}
func (g *getStatisticsTask) BeginTs() Timestamp {
return g.Base.Timestamp
}
func (g *getStatisticsTask) EndTs() Timestamp {
return g.Base.Timestamp
}
func (g *getStatisticsTask) SetTs(ts Timestamp) {
g.Base.Timestamp = ts
}
func (g *getStatisticsTask) OnEnqueue() error {
g.GetStatisticsRequest = &internalpb.GetStatisticsRequest{
Base: &commonpb.MsgBase{},
}
return nil
}
func (g *getStatisticsTask) PreExecute(ctx context.Context) error {
g.DbID = 0
g.collectionName = g.request.GetCollectionName()
g.partitionNames = g.request.GetPartitionNames()
// g.TravelTimestamp = g.request.GetTravelTimestamp()
g.GuaranteeTimestamp = g.request.GetGuaranteeTimestamp()
sp, ctx := trace.StartSpanFromContextWithOperationName(g.TraceCtx(), "Proxy-GetStatistics-PreExecute")
defer sp.Finish()
if g.statisticShardPolicy == nil {
g.statisticShardPolicy = mergeRoundRobinPolicy
}
// TODO: Maybe we should create a new MsgType: GetStatistics?
g.Base.MsgType = commonpb.MsgType_GetPartitionStatistics
g.Base.SourceID = Params.ProxyCfg.GetNodeID()
collID, err := globalMetaCache.GetCollectionID(ctx, g.collectionName)
if err != nil { // err is not nil if collection not exists
return err
}
partIDs, err := getPartitionIDs(ctx, g.collectionName, g.partitionNames)
if err != nil { // err is not nil if partition not exists
return err
}
g.GetStatisticsRequest.DbID = 0 // todo
g.GetStatisticsRequest.CollectionID = collID
if g.TravelTimestamp == 0 {
g.TravelTimestamp = g.BeginTs()
}
err = validateTravelTimestamp(g.TravelTimestamp, g.BeginTs())
if err != nil {
return err
}
g.GuaranteeTimestamp = parseGuaranteeTs(g.GuaranteeTimestamp, g.BeginTs())
deadline, ok := g.TraceCtx().Deadline()
if ok {
g.TimeoutTimestamp = tsoutil.ComposeTSByTime(deadline, 0)
}
// check if collection/partitions are loaded into query node
loaded, unloaded, err := checkFullLoaded(ctx, g.qc, g.collectionName, partIDs)
if err != nil {
g.fromDataCoord = true
g.unloadedPartitionIDs = partIDs
log.Debug("checkFullLoaded failed, try get statistics from DataCoord", zap.Int64("msgID", g.ID()), zap.Error(err))
return nil
}
if len(unloaded) > 0 {
g.fromDataCoord = true
g.unloadedPartitionIDs = unloaded
log.Debug("some partitions has not been loaded, try get statistics from DataCoord", zap.Int64("msgID", g.ID()), zap.String("collection", g.collectionName), zap.Int64s("unloaded partitions", unloaded), zap.Error(err))
}
if len(loaded) > 0 {
g.fromQueryNode = true
g.loadedPartitionIDs = loaded
log.Debug("some partitions has been loaded, try get statistics from QueryNode", zap.Int64("msgID", g.ID()), zap.String("collection", g.collectionName), zap.Int64s("loaded partitions", loaded), zap.Error(err))
}
return nil
}
func (g *getStatisticsTask) Execute(ctx context.Context) error {
sp, ctx := trace.StartSpanFromContextWithOperationName(g.TraceCtx(), "Proxy-GetStatistics-Execute")
defer sp.Finish()
if g.fromQueryNode {
// if request get statistics of collection which is full loaded into query node
// then we need not pass partition ids params
if len(g.request.GetPartitionNames()) == 0 && len(g.unloadedPartitionIDs) == 0 {
g.loadedPartitionIDs = []UniqueID{}
}
err := g.getStatisticsFromQueryNode(ctx)
if err != nil {
return err
}
log.Debug("get collection statistics from QueryNode execute done", zap.Int64("msgID", g.ID()))
}
if g.fromDataCoord {
err := g.getStatisticsFromDataCoord(ctx)
if err != nil {
return err
}
log.Debug("get collection statistics from DataCoord execute done", zap.Int64("msgID", g.ID()))
}
return nil
}
func (g *getStatisticsTask) PostExecute(ctx context.Context) error {
sp, _ := trace.StartSpanFromContextWithOperationName(g.TraceCtx(), "Proxy-GetStatistic-PostExecute")
defer sp.Finish()
tr := timerecord.NewTimeRecorder("getStatisticTask PostExecute")
defer func() {
tr.Elapse("done")
}()
if g.fromQueryNode {
select {
case <-g.TraceCtx().Done():
log.Debug("wait to finish timeout!", zap.Int64("msgID", g.ID()))
return nil
default:
log.Debug("all get statistics are finished or canceled", zap.Int64("msgID", g.ID()))
close(g.resultBuf)
for res := range g.resultBuf {
g.toReduceResults = append(g.toReduceResults, res)
log.Debug("proxy receives one get statistic response", zap.Int64("sourceID", res.GetBase().GetSourceID()), zap.Int64("msgID", g.ID()))
}
}
}
validResults, err := decodeGetStatisticsResults(g.toReduceResults)
if err != nil {
return err
}
result, err := reduceStatisticResponse(validResults)
if err != nil {
return err
}
g.result = &milvuspb.GetStatisticsResponse{
Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
Stats: result,
}
log.Info("get statistics post execute done", zap.Int64("msgID", g.ID()), zap.Any("result", result))
return nil
}
func (g *getStatisticsTask) getStatisticsFromDataCoord(ctx context.Context) error {
collID := g.CollectionID
partIDs := g.unloadedPartitionIDs
req := &datapb.GetPartitionStatisticsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetPartitionStatistics,
MsgID: g.Base.MsgID,
Timestamp: g.Base.Timestamp,
SourceID: g.Base.SourceID,
},
CollectionID: collID,
PartitionIDs: partIDs,
}
result, err := g.dc.GetPartitionStatistics(ctx, req)
if err != nil {
return err
}
if result.Status.ErrorCode != commonpb.ErrorCode_Success {
return errors.New(result.Status.Reason)
}
g.toReduceResults = append(g.toReduceResults, &internalpb.GetStatisticsResponse{
Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
Stats: result.Stats,
})
return nil
}
func (g *getStatisticsTask) getStatisticsFromQueryNode(ctx context.Context) error {
g.GetStatisticsRequest.PartitionIDs = g.loadedPartitionIDs
executeGetStatistics := func(withCache bool) error {
shard2Leaders, err := globalMetaCache.GetShards(ctx, withCache, g.collectionName)
if err != nil {
return err
}
g.resultBuf = make(chan *internalpb.GetStatisticsResponse, len(shard2Leaders))
if err := g.statisticShardPolicy(ctx, g.shardMgr, g.getStatisticsShard, shard2Leaders); err != nil {
log.Warn("failed to get statistics", zap.Int64("msgID", g.ID()), zap.Error(err), zap.String("Shards", fmt.Sprintf("%v", shard2Leaders)))
return err
}
return nil
}
err := executeGetStatistics(WithCache)
if errors.Is(err, errInvalidShardLeaders) || funcutil.IsGrpcErr(err) || errors.Is(err, grpcclient.ErrConnect) {
log.Warn("first get statistics failed, updating shard leader caches and retry",
zap.Int64("msgID", g.ID()), zap.Error(err))
err = executeGetStatistics(WithoutCache)
}
if err != nil {
return fmt.Errorf("fail to get statistics on all shard leaders, err=%w", err)
}
return nil
}
func (g *getStatisticsTask) getStatisticsShard(ctx context.Context, nodeID int64, qn types.QueryNode, channelIDs []string) error {
req := &querypb.GetStatisticsRequest{
Req: g.GetStatisticsRequest,
DmlChannels: channelIDs,
Scope: querypb.DataScope_All,
}
result, err := qn.GetStatistics(ctx, req)
if err != nil {
log.Warn("QueryNode statistic return error", zap.Int64("msgID", g.ID()),
zap.Int64("nodeID", nodeID), zap.Strings("channels", channelIDs), zap.Error(err))
return err
}
if result.GetStatus().GetErrorCode() == commonpb.ErrorCode_NotShardLeader {
log.Warn("QueryNode is not shardLeader", zap.Int64("msgID", g.ID()),
zap.Int64("nodeID", nodeID), zap.Strings("channels", channelIDs))
return errInvalidShardLeaders
}
if result.GetStatus().GetErrorCode() != commonpb.ErrorCode_Success {
log.Warn("QueryNode statistic result error", zap.Int64("msgID", g.ID()),
zap.Int64("nodeID", nodeID), zap.String("reason", result.GetStatus().GetReason()))
return fmt.Errorf("fail to get statistic, QueryNode ID=%d, reason=%s", nodeID, result.GetStatus().GetReason())
}
g.resultBuf <- result
return nil
}
// checkFullLoaded check if collection / partition was fully loaded into QueryNode
// return loaded partitions, unloaded partitions and error
func checkFullLoaded(ctx context.Context, qc types.QueryCoord, collectionName string, searchPartitionIDs []UniqueID) ([]UniqueID, []UniqueID, error) {
var loadedPartitionIDs []UniqueID
var unloadPartitionIDs []UniqueID
// TODO: Consider to check if partition loaded from cache to save rpc.
info, err := globalMetaCache.GetCollectionInfo(ctx, collectionName)
if err != nil {
return nil, nil, fmt.Errorf("GetCollectionInfo failed, collection = %s, err = %s", collectionName, err)
}
// If request to search partitions
if len(searchPartitionIDs) > 0 {
resp, err := qc.ShowPartitions(ctx, &querypb.ShowPartitionsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_ShowPartitions,
SourceID: Params.ProxyCfg.GetNodeID(),
},
CollectionID: info.collID,
PartitionIDs: searchPartitionIDs,
})
if err != nil {
return nil, nil, fmt.Errorf("showPartitions failed, collection = %s, partitionIDs = %v, err = %s", collectionName, searchPartitionIDs, err)
}
if resp.Status.ErrorCode != commonpb.ErrorCode_Success {
return nil, nil, fmt.Errorf("showPartitions failed, collection = %s, partitionIDs = %v, reason = %s", collectionName, searchPartitionIDs, resp.GetStatus().GetReason())
}
for i, percentage := range resp.GetInMemoryPercentages() {
if percentage >= 100 {
loadedPartitionIDs = append(loadedPartitionIDs, resp.GetPartitionIDs()[i])
}
unloadPartitionIDs = append(unloadPartitionIDs, resp.GetPartitionIDs()[i])
}
return loadedPartitionIDs, unloadPartitionIDs, nil
}
// If request to search collection
resp, err := qc.ShowPartitions(ctx, &querypb.ShowPartitionsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_ShowPartitions,
SourceID: Params.ProxyCfg.GetNodeID(),
},
CollectionID: info.collID,
})
if err != nil {
return nil, nil, fmt.Errorf("showPartitions failed, collection = %s, partitionIDs = %v, err = %s", collectionName, searchPartitionIDs, err)
}
if resp.Status.ErrorCode != commonpb.ErrorCode_Success {
return nil, nil, fmt.Errorf("showPartitions failed, collection = %s, partitionIDs = %v, reason = %s", collectionName, searchPartitionIDs, resp.GetStatus().GetReason())
}
loadedMap := make(map[UniqueID]bool)
for i, percentage := range resp.GetInMemoryPercentages() {
if percentage >= 100 {
loadedMap[resp.GetPartitionIDs()[i]] = true
loadedPartitionIDs = append(loadedPartitionIDs, resp.GetPartitionIDs()[i])
}
}
for _, partInfo := range info.partInfo {
if _, ok := loadedMap[partInfo.partitionID]; !ok {
unloadPartitionIDs = append(unloadPartitionIDs, partInfo.partitionID)
}
}
return loadedPartitionIDs, unloadPartitionIDs, nil
}
func decodeGetStatisticsResults(results []*internalpb.GetStatisticsResponse) ([]map[string]string, error) {
ret := make([]map[string]string, len(results))
for i, result := range results {
if result.GetStatus().GetErrorCode() != commonpb.ErrorCode_Success {
return nil, fmt.Errorf("fail to decode result, reason=%s", result.GetStatus().GetReason())
}
ret[i] = funcutil.KeyValuePair2Map(result.GetStats())
}
return ret, nil
}
func reduceStatisticResponse(results []map[string]string) ([]*commonpb.KeyValuePair, error) {
mergedResults := map[string]interface{}{
"row_count": int64(0),
}
fieldMethod := map[string]func(string) error{
"row_count": func(str string) error {
count, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return err
}
mergedResults["row_count"] = mergedResults["row_count"].(int64) + count
return nil
},
}
err := funcutil.MapReduce(results, fieldMethod)
stringMap := make(map[string]string)
for k, v := range mergedResults {
stringMap[k] = fmt.Sprint(v)
}
return funcutil.Map2KeyValuePair(stringMap), err
}
// implement Task
// try to compatible with old API (getCollectionStatistics & getPartitionStatistics)
//type getPartitionStatisticsTask struct {
// getStatisticsTask
// request *milvuspb.GetPartitionStatisticsRequest
// result *milvuspb.GetPartitionStatisticsResponse
//}
//
//func (g *getPartitionStatisticsTask) PreExecute(ctx context.Context) error {
// g.getStatisticsTask.DbID = 0
// g.getStatisticsTask.collectionName = g.request.GetCollectionName()
// g.getStatisticsTask.partitionNames = []string{g.request.GetPartitionName()}
// // g.TravelTimestamp = g.request.GetTravelTimestamp()
// // g.GuaranteeTimestamp = g.request.GetGuaranteeTimestamp()
// return g.getStatisticsTask.PreExecute(ctx)
//}
//
//func (g *getPartitionStatisticsTask) Execute(ctx context.Context) error {
// if g.fromQueryNode {
// err := g.getStatisticsTask.Execute(ctx)
// if err != nil {
// return err
// }
// log.Debug("get partition statistics from QueryNode execute done", zap.Int64("msgID", g.ID()))
// }
// if g.fromDataCoord {
// collID := g.CollectionID
// partIDs := g.unloadedPartitionIDs
//
// req := &datapb.GetPartitionStatisticsRequest{
// Base: &commonpb.MsgBase{
// MsgType: commonpb.MsgType_GetPartitionStatistics,
// MsgID: g.Base.MsgID,
// Timestamp: g.Base.Timestamp,
// SourceID: g.Base.SourceID,
// },
// CollectionID: collID,
// PartitionIDs: partIDs,
// }
//
// result, err := g.dc.GetPartitionStatistics(ctx, req)
// if err != nil {
// return err
// }
// if result.Status.ErrorCode != commonpb.ErrorCode_Success {
// return errors.New(result.Status.Reason)
// }
// g.toReduceResults = append(g.toReduceResults, &internalpb.GetStatisticsResponse{
// Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
// Stats: result.Stats,
// })
// log.Debug("get partition statistics from DataCoord execute done", zap.Int64("msgID", g.ID()))
// return nil
// }
// return nil
//}
//
//func (g *getPartitionStatisticsTask) PostExecute(ctx context.Context) error {
// err := g.getStatisticsTask.PostExecute(ctx)
// if err != nil {
// return err
// }
// g.result = &milvuspb.GetPartitionStatisticsResponse{
// Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
// Stats: g.innerResult,
// }
// return nil
//}
//
//type getCollectionStatisticsTask struct {
// getStatisticsTask
// request *milvuspb.GetCollectionStatisticsRequest
// result *milvuspb.GetCollectionStatisticsResponse
//}
//
//func (g *getCollectionStatisticsTask) PreExecute(ctx context.Context) error {
// g.getStatisticsTask.DbID = 0
// g.getStatisticsTask.collectionName = g.request.GetCollectionName()
// g.getStatisticsTask.partitionNames = []string{}
// // g.TravelTimestamp = g.request.GetTravelTimestamp()
// // g.GuaranteeTimestamp = g.request.GetGuaranteeTimestamp()
// return g.getStatisticsTask.PreExecute(ctx)
//}
//
//func (g *getCollectionStatisticsTask) Execute(ctx context.Context) error {
// if g.fromQueryNode {
// // if you get entire collection, we need to pass partition ids param.
// if len(g.unloadedPartitionIDs) == 0 {
// g.GetStatisticsRequest.PartitionIDs = nil
// }
// err := g.getStatisticsTask.Execute(ctx)
// if err != nil {
// return err
// }
// log.Debug("get collection statistics from QueryNode execute done", zap.Int64("msgID", g.ID()))
// }
// if g.fromDataCoord {
// collID := g.CollectionID
// partIDs := g.unloadedPartitionIDs
//
// // all collection has not been loaded, get statistics from datacoord
// if len(g.GetStatisticsRequest.PartitionIDs) == 0 {
// req := &datapb.GetCollectionStatisticsRequest{
// Base: &commonpb.MsgBase{
// MsgType: commonpb.MsgType_GetCollectionStatistics,
// MsgID: g.Base.MsgID,
// Timestamp: g.Base.Timestamp,
// SourceID: g.Base.SourceID,
// },
// CollectionID: collID,
// }
//
// result, err := g.dc.GetCollectionStatistics(ctx, req)
// if err != nil {
// return err
// }
// if result.Status.ErrorCode != commonpb.ErrorCode_Success {
// return errors.New(result.Status.Reason)
// }
// g.toReduceResults = append(g.toReduceResults, &internalpb.GetStatisticsResponse{
// Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
// Stats: result.Stats,
// })
// } else { // some partitions have been loaded, get some partition statistics from datacoord
// req := &datapb.GetPartitionStatisticsRequest{
// Base: &commonpb.MsgBase{
// MsgType: commonpb.MsgType_GetPartitionStatistics,
// MsgID: g.Base.MsgID,
// Timestamp: g.Base.Timestamp,
// SourceID: g.Base.SourceID,
// },
// CollectionID: collID,
// PartitionIDs: partIDs,
// }
//
// result, err := g.dc.GetPartitionStatistics(ctx, req)
// if err != nil {
// return err
// }
// if result.Status.ErrorCode != commonpb.ErrorCode_Success {
// return errors.New(result.Status.Reason)
// }
// g.toReduceResults = append(g.toReduceResults, &internalpb.GetStatisticsResponse{
// Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
// Stats: result.Stats,
// })
// }
// log.Debug("get collection statistics from DataCoord execute done", zap.Int64("msgID", g.ID()))
// return nil
// }
// return nil
//}
//
//func (g *getCollectionStatisticsTask) PostExecute(ctx context.Context) error {
// err := g.getStatisticsTask.PostExecute(ctx)
// if err != nil {
// return err
// }
// g.result = &milvuspb.GetCollectionStatisticsResponse{
// Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
// Stats: g.innerResult,
// }
// return nil
//}
// old version of get statistics
// please remove it after getStatisticsTask below is stable
type getCollectionStatisticsTask struct {
Condition
*milvuspb.GetCollectionStatisticsRequest
ctx context.Context
dataCoord types.DataCoord
result *milvuspb.GetCollectionStatisticsResponse
collectionID UniqueID
}
func (g *getCollectionStatisticsTask) TraceCtx() context.Context {
return g.ctx
}
func (g *getCollectionStatisticsTask) ID() UniqueID {
return g.Base.MsgID
}
func (g *getCollectionStatisticsTask) SetID(uid UniqueID) {
g.Base.MsgID = uid
}
func (g *getCollectionStatisticsTask) Name() string {
return GetCollectionStatisticsTaskName
}
func (g *getCollectionStatisticsTask) Type() commonpb.MsgType {
return g.Base.MsgType
}
func (g *getCollectionStatisticsTask) BeginTs() Timestamp {
return g.Base.Timestamp
}
func (g *getCollectionStatisticsTask) EndTs() Timestamp {
return g.Base.Timestamp
}
func (g *getCollectionStatisticsTask) SetTs(ts Timestamp) {
g.Base.Timestamp = ts
}
func (g *getCollectionStatisticsTask) OnEnqueue() error {
g.Base = &commonpb.MsgBase{}
return nil
}
func (g *getCollectionStatisticsTask) PreExecute(ctx context.Context) error {
g.Base.MsgType = commonpb.MsgType_GetCollectionStatistics
g.Base.SourceID = Params.ProxyCfg.GetNodeID()
return nil
}
func (g *getCollectionStatisticsTask) Execute(ctx context.Context) error {
collID, err := globalMetaCache.GetCollectionID(ctx, g.CollectionName)
if err != nil {
return err
}
g.collectionID = collID
req := &datapb.GetCollectionStatisticsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetCollectionStatistics,
MsgID: g.Base.MsgID,
Timestamp: g.Base.Timestamp,
SourceID: g.Base.SourceID,
},
CollectionID: collID,
}
result, _ := g.dataCoord.GetCollectionStatistics(ctx, req)
if result == nil {
return errors.New("get collection statistics resp is nil")
}
if result.Status.ErrorCode != commonpb.ErrorCode_Success {
return errors.New(result.Status.Reason)
}
g.result = &milvuspb.GetCollectionStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
},
Stats: result.Stats,
}
return nil
}
func (g *getCollectionStatisticsTask) PostExecute(ctx context.Context) error {
return nil
}
type getPartitionStatisticsTask struct {
Condition
*milvuspb.GetPartitionStatisticsRequest
ctx context.Context
dataCoord types.DataCoord
result *milvuspb.GetPartitionStatisticsResponse
collectionID UniqueID
}
func (g *getPartitionStatisticsTask) TraceCtx() context.Context {
return g.ctx
}
func (g *getPartitionStatisticsTask) ID() UniqueID {
return g.Base.MsgID
}
func (g *getPartitionStatisticsTask) SetID(uid UniqueID) {
g.Base.MsgID = uid
}
func (g *getPartitionStatisticsTask) Name() string {
return GetPartitionStatisticsTaskName
}
func (g *getPartitionStatisticsTask) Type() commonpb.MsgType {
return g.Base.MsgType
}
func (g *getPartitionStatisticsTask) BeginTs() Timestamp {
return g.Base.Timestamp
}
func (g *getPartitionStatisticsTask) EndTs() Timestamp {
return g.Base.Timestamp
}
func (g *getPartitionStatisticsTask) SetTs(ts Timestamp) {
g.Base.Timestamp = ts
}
func (g *getPartitionStatisticsTask) OnEnqueue() error {
g.Base = &commonpb.MsgBase{}
return nil
}
func (g *getPartitionStatisticsTask) PreExecute(ctx context.Context) error {
g.Base.MsgType = commonpb.MsgType_GetPartitionStatistics
g.Base.SourceID = Params.ProxyCfg.GetNodeID()
return nil
}
func (g *getPartitionStatisticsTask) Execute(ctx context.Context) error {
collID, err := globalMetaCache.GetCollectionID(ctx, g.CollectionName)
if err != nil {
return err
}
g.collectionID = collID
partitionID, err := globalMetaCache.GetPartitionID(ctx, g.CollectionName, g.PartitionName)
if err != nil {
return err
}
req := &datapb.GetPartitionStatisticsRequest{
Base: &commonpb.MsgBase{
MsgType: commonpb.MsgType_GetPartitionStatistics,
MsgID: g.Base.MsgID,
Timestamp: g.Base.Timestamp,
SourceID: g.Base.SourceID,
},
CollectionID: collID,
PartitionIDs: []int64{partitionID},
}
result, _ := g.dataCoord.GetPartitionStatistics(ctx, req)
if result == nil {
return errors.New("get partition statistics resp is nil")
}
if result.Status.ErrorCode != commonpb.ErrorCode_Success {
return errors.New(result.Status.Reason)
}
g.result = &milvuspb.GetPartitionStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_Success,
Reason: "",
},
Stats: result.Stats,
}
return nil
}
func (g *getPartitionStatisticsTask) PostExecute(ctx context.Context) error {
return nil
}

View File

@ -148,6 +148,10 @@ func (client *queryNodeClientMock) GetMetrics(ctx context.Context, req *milvuspb
return client.grpcClient.GetMetrics(ctx, req)
}
func (client *queryNodeClientMock) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return client.grpcClient.GetStatistics(ctx, req)
}
func (client *queryNodeClientMock) Search(ctx context.Context, req *querypb.SearchRequest) (*internalpb.SearchResults, error) {
return client.grpcClient.Search(ctx, req)
}

View File

@ -18,6 +18,7 @@ package querynode
import (
"context"
"errors"
"fmt"
"sync"
@ -90,6 +91,191 @@ func (node *QueryNode) GetStatisticsChannel(ctx context.Context) (*milvuspb.Stri
}, nil
}
func (node *QueryNode) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
log.Debug("received GetStatisticsRequest",
zap.Int64("msgID", req.GetReq().GetBase().GetMsgID()),
zap.Strings("vChannels", req.GetDmlChannels()),
zap.Int64s("segmentIDs", req.GetSegmentIDs()),
zap.Uint64("guaranteeTimestamp", req.GetReq().GetGuaranteeTimestamp()),
zap.Uint64("timeTravel", req.GetReq().GetTravelTimestamp()))
failRet := &internalpb.GetStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
},
}
toReduceResults := make([]*internalpb.GetStatisticsResponse, 0)
runningGp, runningCtx := errgroup.WithContext(ctx)
mu := &sync.Mutex{}
for _, ch := range req.GetDmlChannels() {
ch := ch
req := &querypb.GetStatisticsRequest{
Req: req.Req,
DmlChannels: []string{ch},
SegmentIDs: req.SegmentIDs,
FromShardLeader: req.FromShardLeader,
Scope: req.Scope,
}
runningGp.Go(func() error {
ret, err := node.getStatisticsWithDmlChannel(runningCtx, req, ch)
mu.Lock()
defer mu.Unlock()
if err != nil {
failRet.Status.Reason = err.Error()
failRet.Status.ErrorCode = commonpb.ErrorCode_UnexpectedError
return err
}
if ret.GetStatus().GetErrorCode() != commonpb.ErrorCode_Success {
failRet.Status.Reason = ret.Status.Reason
failRet.Status.ErrorCode = ret.Status.ErrorCode
return fmt.Errorf("%s", ret.Status.Reason)
}
toReduceResults = append(toReduceResults, ret)
return nil
})
}
if err := runningGp.Wait(); err != nil {
return failRet, nil
}
ret, err := reduceStatisticResponse(toReduceResults)
if err != nil {
failRet.Status.ErrorCode = commonpb.ErrorCode_UnexpectedError
failRet.Status.Reason = err.Error()
return failRet, nil
}
return ret, nil
}
func (node *QueryNode) getStatisticsWithDmlChannel(ctx context.Context, req *queryPb.GetStatisticsRequest, dmlChannel string) (*internalpb.GetStatisticsResponse, error) {
failRet := &internalpb.GetStatisticsResponse{
Status: &commonpb.Status{
ErrorCode: commonpb.ErrorCode_UnexpectedError,
},
}
if !node.isHealthy() {
failRet.Status.Reason = msgQueryNodeIsUnhealthy(Params.QueryNodeCfg.GetNodeID())
return failRet, nil
}
msgID := req.GetReq().GetBase().GetMsgID()
log.Debug("received GetStatisticRequest",
zap.Int64("msgID", msgID),
zap.Bool("fromShardLeader", req.GetFromShardLeader()),
zap.String("vChannel", dmlChannel),
zap.Int64s("segmentIDs", req.GetSegmentIDs()),
zap.Uint64("guaranteeTimestamp", req.GetReq().GetGuaranteeTimestamp()),
zap.Uint64("timeTravel", req.GetReq().GetTravelTimestamp()))
if node.queryShardService == nil {
failRet.Status.Reason = "queryShardService is nil"
return failRet, nil
}
qs, err := node.queryShardService.getQueryShard(dmlChannel)
if err != nil {
log.Warn("get statistics failed, failed to get query shard",
zap.Int64("msgID", msgID),
zap.String("dml channel", dmlChannel),
zap.Error(err))
failRet.Status.ErrorCode = commonpb.ErrorCode_NotShardLeader
failRet.Status.Reason = err.Error()
return failRet, nil
}
log.Debug("start do statistics",
zap.Int64("msgID", msgID),
zap.Bool("fromShardLeader", req.GetFromShardLeader()),
zap.String("vChannel", dmlChannel),
zap.Int64s("segmentIDs", req.GetSegmentIDs()))
tr := timerecord.NewTimeRecorder("")
waitCanDo := func(ctx context.Context) error {
l := node.tSafeReplica.WatchChannel(dmlChannel)
defer l.Unregister()
for {
select {
case <-l.On():
serviceTime, err := qs.getServiceableTime(dmlChannel)
if err != nil {
return err
}
guaranteeTs := req.GetReq().GetGuaranteeTimestamp()
if guaranteeTs <= serviceTime {
return nil
}
case <-ctx.Done():
return errors.New("get statistics context timeout")
}
}
}
if req.FromShardLeader {
historicalTask := newStatistics(ctx, req, querypb.DataScope_Historical, qs, waitCanDo)
err := historicalTask.Execute(ctx)
if err != nil {
failRet.Status.Reason = err.Error()
return failRet, nil
}
tr.Elapse(fmt.Sprintf("do statistics done, msgID = %d, fromSharedLeader = %t, vChannel = %s, segmentIDs = %v",
msgID, req.GetFromShardLeader(), dmlChannel, req.GetSegmentIDs()))
failRet.Status.ErrorCode = commonpb.ErrorCode_Success
return historicalTask.Ret, nil
}
// from Proxy
cluster, ok := qs.clusterService.getShardCluster(dmlChannel)
if !ok {
failRet.Status.ErrorCode = commonpb.ErrorCode_NotShardLeader
failRet.Status.Reason = fmt.Sprintf("channel %s leader is not here", dmlChannel)
return failRet, nil
}
statisticCtx, cancel := context.WithCancel(ctx)
defer cancel()
var results []*internalpb.GetStatisticsResponse
var streamingResult *internalpb.GetStatisticsResponse
var errCluster error
withStreaming := func(ctx context.Context) error {
streamingTask := newStatistics(ctx, req, querypb.DataScope_Streaming, qs, waitCanDo)
err := streamingTask.Execute(ctx)
if err != nil {
return err
}
streamingResult = streamingTask.Ret
return nil
}
// shard leader dispatches request to its shard cluster
results, errCluster = cluster.GetStatistics(statisticCtx, req, withStreaming)
if errCluster != nil {
log.Warn("get statistics on cluster failed", zap.Int64("msgID", msgID), zap.Int64("collectionID", req.Req.GetCollectionID()), zap.Error(errCluster))
failRet.Status.Reason = errCluster.Error()
return failRet, nil
}
tr.Elapse(fmt.Sprintf("start reduce statistic result, msgID = %d, fromSharedLeader = %t, vChannel = %s, segmentIDs = %v",
msgID, req.GetFromShardLeader(), dmlChannel, req.GetSegmentIDs()))
results = append(results, streamingResult)
ret, err := reduceStatisticResponse(results)
if err != nil {
failRet.Status.Reason = err.Error()
return failRet, nil
}
log.Debug("reduce statistic result done", zap.Int64("msgID", msgID), zap.Any("results", ret))
tr.Elapse(fmt.Sprintf("do statistics done, msgID = %d, fromSharedLeader = %t, vChannel = %s, segmentIDs = %v",
msgID, req.GetFromShardLeader(), dmlChannel, req.GetSegmentIDs()))
failRet.Status.ErrorCode = commonpb.ErrorCode_Success
return ret, nil
}
// WatchDmChannels create consumers on dmChannels to receive Incremental datawhich is the important part of real-time query
func (node *QueryNode) WatchDmChannels(ctx context.Context, in *queryPb.WatchDmChannelsRequest) (*commonpb.Status, error) {
code := node.stateCode.Load().(internalpb.StateCode)

View File

@ -532,6 +532,48 @@ func TestImpl_searchWithDmlChannel(t *testing.T) {
assert.NoError(t, err)
}
func TestImpl_GetCollectionStatistics(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
node, err := genSimpleQueryNode(ctx)
defer node.Stop()
require.NoError(t, err)
req, err := genGetCollectionStatisticRequest()
require.NoError(t, err)
node.queryShardService.addQueryShard(defaultCollectionID, defaultDMLChannel, defaultReplicaID)
_, err = node.GetStatistics(ctx, &queryPb.GetStatisticsRequest{
Req: req,
FromShardLeader: false,
DmlChannels: []string{defaultDMLChannel},
})
assert.NoError(t, err)
}
func TestImpl_GetPartitionStatistics(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
node, err := genSimpleQueryNode(ctx)
defer node.Stop()
require.NoError(t, err)
req, err := genGetPartitionStatisticRequest()
require.NoError(t, err)
node.queryShardService.addQueryShard(defaultCollectionID, defaultDMLChannel, defaultReplicaID)
_, err = node.GetStatistics(ctx, &queryPb.GetStatisticsRequest{
Req: req,
FromShardLeader: false,
DmlChannels: []string{defaultDMLChannel},
})
assert.NoError(t, err)
}
func TestImpl_Query(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

View File

@ -1509,6 +1509,23 @@ func genSimpleRetrievePlan(collection *Collection) (*RetrievePlan, error) {
return plan, err2
}
func genGetCollectionStatisticRequest() (*internalpb.GetStatisticsRequest, error) {
return &internalpb.GetStatisticsRequest{
Base: genCommonMsgBase(commonpb.MsgType_GetCollectionStatistics),
DbID: 0,
CollectionID: defaultCollectionID,
}, nil
}
func genGetPartitionStatisticRequest() (*internalpb.GetStatisticsRequest, error) {
return &internalpb.GetStatisticsRequest{
Base: genCommonMsgBase(commonpb.MsgType_GetPartitionStatistics),
DbID: 0,
CollectionID: defaultCollectionID,
PartitionIDs: []UniqueID{defaultPartitionID},
}, nil
}
func genSearchRequest(nq int64, indexType string, schema *schemapb.CollectionSchema) (*internalpb.SearchRequest, error) {
placeHolder, err := genPlaceHolderGroup(nq)
if err != nil {

View File

@ -19,6 +19,9 @@ package querynode
import (
"fmt"
"math"
"strconv"
"github.com/milvus-io/milvus/internal/util/funcutil"
"go.uber.org/zap"
@ -31,6 +34,45 @@ import (
"github.com/milvus-io/milvus/internal/util/typeutil"
)
func reduceStatisticResponse(results []*internalpb.GetStatisticsResponse) (*internalpb.GetStatisticsResponse, error) {
mergedResults := map[string]interface{}{
"row_count": int64(0),
}
fieldMethod := map[string]func(string) error{
"row_count": func(str string) error {
count, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return err
}
mergedResults["row_count"] = mergedResults["row_count"].(int64) + count
return nil
},
}
for _, partialResult := range results {
for _, pair := range partialResult.Stats {
fn, ok := fieldMethod[pair.Key]
if !ok {
return nil, fmt.Errorf("unknown statistic field: %s", pair.Key)
}
if err := fn(pair.Value); err != nil {
return nil, err
}
}
}
stringMap := make(map[string]string)
for k, v := range mergedResults {
stringMap[k] = fmt.Sprint(v)
}
ret := &internalpb.GetStatisticsResponse{
Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
Stats: funcutil.Map2KeyValuePair(stringMap),
}
return ret, nil
}
func reduceSearchResults(results []*internalpb.SearchResults, nq int64, topk int64, metricType string) (*internalpb.SearchResults, error) {
searchResultData, err := decodeSearchResults(results)
if err != nil {

View File

@ -224,6 +224,18 @@ func deleteSegment(segment *Segment) {
zap.String("segmentType", segment.getType().String()))
}
func (s *Segment) getRealCount() int64 {
/*
int64_t
GetRealCount(CSegmentInterface c_segment);
*/
if s.segmentPtr == nil {
return -1
}
var rowCount = C.GetRealCount(s.segmentPtr)
return int64(rowCount)
}
func (s *Segment) getRowCount() int64 {
/*
long int

View File

@ -246,7 +246,7 @@ func TestSegment_getDeletedCount(t *testing.T) {
var deletedCount = segment.getDeletedCount()
// TODO: assert.Equal(t, deletedCount, len(ids))
assert.Equal(t, deletedCount, int64(0))
assert.Equal(t, deletedCount, int64(len(pks)))
deleteCollection(collection)

View File

@ -80,6 +80,7 @@ type segmentEvent struct {
}
type shardQueryNode interface {
GetStatistics(context.Context, *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error)
Search(context.Context, *querypb.SearchRequest) (*internalpb.SearchResults, error)
Query(context.Context, *querypb.QueryRequest) (*internalpb.RetrieveResults, error)
ReleaseSegments(ctx context.Context, in *querypb.ReleaseSegmentsRequest) (*commonpb.Status, error)
@ -718,6 +719,89 @@ func (sc *ShardCluster) segmentsOnline(segments []shardSegmentInfo) bool {
return true
}
// GetStatistics returns the statistics on the shard cluster.
func (sc *ShardCluster) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest, withStreaming withStreaming) ([]*internalpb.GetStatisticsResponse, error) {
if !sc.serviceable() {
return nil, fmt.Errorf("ShardCluster for %s replicaID %d is no available", sc.vchannelName, sc.replicaID)
}
if !funcutil.SliceContain(req.GetDmlChannels(), sc.vchannelName) {
return nil, fmt.Errorf("ShardCluster for %s does not match request channels :%v", sc.vchannelName, req.GetDmlChannels())
}
// get node allocation and maintains the inUse reference count
segAllocs, versionID := sc.segmentAllocations(req.GetReq().GetPartitionIDs())
defer sc.finishUsage(versionID)
log.Debug("cluster segment distribution", zap.Int("len", len(segAllocs)))
for nodeID, segmentIDs := range segAllocs {
log.Debug("segments distribution", zap.Int64("nodeID", nodeID), zap.Int64s("segments", segmentIDs))
}
// concurrent visiting nodes
var wg sync.WaitGroup
reqCtx, cancel := context.WithCancel(ctx)
defer cancel()
var err error
var resultMut sync.Mutex
results := make([]*internalpb.GetStatisticsResponse, 0, len(segAllocs)) // count(nodes) + 1(growing)
// detect corresponding streaming search is done
wg.Add(1)
go func() {
defer wg.Done()
streamErr := withStreaming(reqCtx)
resultMut.Lock()
defer resultMut.Unlock()
if streamErr != nil {
cancel()
// not set cancel error
if !errors.Is(streamErr, context.Canceled) {
err = fmt.Errorf("stream operation failed: %w", streamErr)
}
}
}()
// dispatch request to followers
for nodeID, segments := range segAllocs {
nodeReq := &querypb.GetStatisticsRequest{
Req: req.GetReq(),
DmlChannels: req.GetDmlChannels(),
FromShardLeader: true,
Scope: querypb.DataScope_Historical,
SegmentIDs: segments,
}
node, ok := sc.getNode(nodeID)
if !ok { // meta mismatch, report error
return nil, fmt.Errorf("ShardCluster for %s replicaID %d is no available", sc.vchannelName, sc.replicaID)
}
wg.Add(1)
go func() {
defer wg.Done()
partialResult, nodeErr := node.client.GetStatistics(reqCtx, nodeReq)
resultMut.Lock()
defer resultMut.Unlock()
if nodeErr != nil || partialResult.GetStatus().GetErrorCode() != commonpb.ErrorCode_Success {
cancel()
// not set cancel error
if !errors.Is(nodeErr, context.Canceled) {
err = fmt.Errorf("GetStatistic %d failed, reason %s err %w", node.nodeID, partialResult.GetStatus().GetReason(), nodeErr)
}
return
}
results = append(results, partialResult)
}()
}
wg.Wait()
if err != nil {
log.Error(err.Error())
return nil, err
}
return results, nil
}
// Search preforms search operation on shard cluster.
func (sc *ShardCluster) Search(ctx context.Context, req *querypb.SearchRequest, withStreaming withStreaming) ([]*internalpb.SearchResults, error) {
if !sc.serviceable() {

View File

@ -48,6 +48,8 @@ func (m *mockSegmentDetector) watchSegments(collectionID int64, replicaID int64,
}
type mockShardQueryNode struct {
statisticResponse *internalpb.GetStatisticsResponse
statisticErr error
searchResult *internalpb.SearchResults
searchErr error
queryResult *internalpb.RetrieveResults
@ -56,6 +58,10 @@ type mockShardQueryNode struct {
releaseSegmentsErr error
}
func (m *mockShardQueryNode) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return m.statisticResponse, m.statisticErr
}
func (m *mockShardQueryNode) Search(_ context.Context, _ *querypb.SearchRequest) (*internalpb.SearchResults, error) {
return m.searchResult, m.searchErr
}
@ -74,6 +80,14 @@ func (m *mockShardQueryNode) Stop() error {
func buildMockQueryNode(nodeID int64, addr string) shardQueryNode {
return &mockShardQueryNode{
statisticResponse: &internalpb.GetStatisticsResponse{
Stats: []*commonpb.KeyValuePair{
{
Key: "row_count",
Value: "0",
},
},
},
searchResult: &internalpb.SearchResults{},
queryResult: &internalpb.RetrieveResults{},
}
@ -1522,6 +1536,282 @@ func TestShardCluster_Query(t *testing.T) {
}
func TestShardCluster_GetStatistics(t *testing.T) {
collectionID := int64(1)
vchannelName := "dml_1_1_v0"
replicaID := int64(0)
ctx := context.Background()
t.Run("get statistics on unavailable cluster", func(t *testing.T) {
nodeEvents := []nodeEvent{
{
nodeID: 1,
nodeAddr: "addr_1",
},
{
nodeID: 2,
nodeAddr: "addr_2",
},
{
nodeID: 3,
nodeAddr: "addr_3",
},
}
segmentEvents := []segmentEvent{
{
segmentID: 1,
nodeIDs: []int64{1},
state: segmentStateOffline,
},
{
segmentID: 2,
nodeIDs: []int64{2},
state: segmentStateOffline,
},
{
segmentID: 3,
nodeIDs: []int64{3},
state: segmentStateOffline,
},
}
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{initNodes: nodeEvents}, &mockSegmentDetector{
initSegments: segmentEvents,
}, buildMockQueryNode)
defer sc.Close()
require.EqualValues(t, unavailable, sc.state.Load())
_, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName},
}, streamingDoNothing)
assert.Error(t, err)
})
t.Run("get statistics on wrong channel", func(t *testing.T) {
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{}, &mockSegmentDetector{}, buildMockQueryNode)
defer sc.Close()
_, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName + "_suffix"},
}, streamingDoNothing)
assert.Error(t, err)
})
t.Run("normal get statistics", func(t *testing.T) {
nodeEvents := []nodeEvent{
{
nodeID: 1,
nodeAddr: "addr_1",
},
{
nodeID: 2,
nodeAddr: "addr_2",
},
}
segmentEvents := []segmentEvent{
{
segmentID: 1,
nodeIDs: []int64{1},
state: segmentStateLoaded,
},
{
segmentID: 2,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
{
segmentID: 3,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
}
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{
initNodes: nodeEvents,
}, &mockSegmentDetector{
initSegments: segmentEvents,
}, buildMockQueryNode)
defer sc.Close()
// setup first version
sc.SyncSegments(nil, segmentStateLoaded)
require.EqualValues(t, available, sc.state.Load())
result, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName},
}, streamingDoNothing)
assert.NoError(t, err)
assert.Equal(t, len(nodeEvents), len(result))
})
t.Run("with streaming fail", func(t *testing.T) {
nodeEvents := []nodeEvent{
{
nodeID: 1,
nodeAddr: "addr_1",
},
{
nodeID: 2,
nodeAddr: "addr_2",
},
}
segmentEvents := []segmentEvent{
{
segmentID: 1,
nodeIDs: []int64{1},
state: segmentStateLoaded,
},
{
segmentID: 2,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
{
segmentID: 3,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
}
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{
initNodes: nodeEvents,
}, &mockSegmentDetector{
initSegments: segmentEvents,
}, buildMockQueryNode)
defer sc.Close()
// setup first version
sc.SyncSegments(nil, segmentStateLoaded)
require.EqualValues(t, available, sc.state.Load())
_, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName},
}, func(ctx context.Context) error { return errors.New("mocked") })
assert.Error(t, err)
})
t.Run("partial fail", func(t *testing.T) {
nodeEvents := []nodeEvent{
{
nodeID: 1,
nodeAddr: "addr_1",
},
{
nodeID: 2,
nodeAddr: "addr_2",
},
}
segmentEvents := []segmentEvent{
{
segmentID: 1,
nodeIDs: []int64{1},
state: segmentStateLoaded,
},
{
segmentID: 2,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
{
segmentID: 3,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
}
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{
initNodes: nodeEvents,
}, &mockSegmentDetector{
initSegments: segmentEvents,
}, func(nodeID int64, addr string) shardQueryNode {
if nodeID != 2 { // hard code error one
return buildMockQueryNode(nodeID, addr)
}
return &mockShardQueryNode{
statisticErr: errors.New("mocked error"),
searchErr: errors.New("mocked error"),
queryErr: errors.New("mocked error"),
}
})
defer sc.Close()
// setup first version
sc.SyncSegments(nil, segmentStateLoaded)
require.EqualValues(t, available, sc.state.Load())
_, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName},
}, streamingDoNothing)
assert.Error(t, err)
})
t.Run("test meta error", func(t *testing.T) {
nodeEvents := []nodeEvent{
{
nodeID: 1,
nodeAddr: "addr_1",
},
{
nodeID: 2,
nodeAddr: "addr_2",
},
}
segmentEvents := []segmentEvent{
{
segmentID: 1,
nodeIDs: []int64{1},
state: segmentStateLoaded,
},
{
segmentID: 2,
nodeIDs: []int64{2},
state: segmentStateLoaded,
},
}
sc := NewShardCluster(collectionID, replicaID, vchannelName,
&mockNodeDetector{
initNodes: nodeEvents,
}, &mockSegmentDetector{
initSegments: segmentEvents,
}, buildMockQueryNode)
//mock meta error
sc.mut.Lock()
sc.segments[3] = shardSegmentInfo{
segmentID: 3,
nodeID: 3, // node does not exist
state: segmentStateLoaded,
}
sc.mut.Unlock()
defer sc.Close()
// setup first version
sc.SyncSegments(nil, segmentStateLoaded)
require.EqualValues(t, available, sc.state.Load())
_, err := sc.GetStatistics(ctx, &querypb.GetStatisticsRequest{
DmlChannels: []string{vchannelName},
}, streamingDoNothing)
assert.Error(t, err)
})
}
func TestShardCluster_Version(t *testing.T) {
collectionID := int64(1)
vchannelName := "dml_1_1_v0"

View File

@ -0,0 +1,166 @@
// 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.
package querynode
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestHistorical_statistic(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
t.Run("test statistics", func(t *testing.T) {
his, err := genSimpleReplicaWithSealSegment(ctx)
assert.NoError(t, err)
_, _, _, err = statisticHistorical(his, defaultCollectionID, nil, []UniqueID{defaultSegmentID})
assert.NoError(t, err)
})
t.Run("test no collection - statistics partitions", func(t *testing.T) {
his, err := genSimpleReplicaWithSealSegment(ctx)
assert.NoError(t, err)
err = his.removeCollection(defaultCollectionID)
assert.NoError(t, err)
_, _, _, err = statisticHistorical(his, defaultCollectionID, nil, nil)
assert.Error(t, err)
})
t.Run("test no collection - statistics all collection", func(t *testing.T) {
his, err := genSimpleReplicaWithSealSegment(ctx)
assert.NoError(t, err)
err = his.removeCollection(defaultCollectionID)
assert.NoError(t, err)
_, _, _, err = statisticHistorical(his, defaultCollectionID, []UniqueID{defaultPartitionID}, nil)
assert.Error(t, err)
})
t.Run("test load partition and partition has been released", func(t *testing.T) {
his, err := genSimpleReplicaWithSealSegment(ctx)
assert.NoError(t, err)
col, err := his.getCollectionByID(defaultCollectionID)
assert.NoError(t, err)
col.setLoadType(loadTypePartition)
err = his.removePartition(defaultPartitionID)
assert.NoError(t, err)
_, _, _, err = statisticHistorical(his, defaultCollectionID, nil, nil)
assert.Error(t, err)
})
t.Run("test no partition in collection", func(t *testing.T) {
his, err := genSimpleReplicaWithSealSegment(ctx)
assert.NoError(t, err)
err = his.removePartition(defaultPartitionID)
assert.NoError(t, err)
res, _, ids, err := statisticHistorical(his, defaultCollectionID, nil, nil)
assert.Equal(t, 0, len(res))
assert.Equal(t, 0, len(ids))
assert.NoError(t, err)
})
}
func TestStreaming_statistics(t *testing.T) {
t.Run("test statistics", func(t *testing.T) {
streaming, err := genSimpleReplicaWithGrowingSegment()
assert.NoError(t, err)
res, _, _, err := statisticStreaming(streaming,
defaultCollectionID,
[]UniqueID{defaultPartitionID},
defaultDMLChannel)
assert.NoError(t, err)
assert.Len(t, res, 1)
})
t.Run("test run empty partition", func(t *testing.T) {
streaming, err := genSimpleReplicaWithGrowingSegment()
assert.NoError(t, err)
res, _, _, err := statisticStreaming(streaming,
defaultCollectionID,
[]UniqueID{defaultPartitionID},
defaultDMLChannel)
assert.NoError(t, err)
assert.Len(t, res, 1)
})
t.Run("test run empty partition and loadCollection", func(t *testing.T) {
streaming, err := genSimpleReplicaWithGrowingSegment()
assert.NoError(t, err)
col, err := streaming.getCollectionByID(defaultCollectionID)
assert.NoError(t, err)
col.setLoadType(loadTypeCollection)
err = streaming.removePartition(defaultPartitionID)
assert.NoError(t, err)
res, _, _, err := statisticStreaming(streaming,
defaultCollectionID,
[]UniqueID{defaultPartitionID},
defaultDMLChannel)
assert.Error(t, err)
assert.Equal(t, 0, len(res))
})
t.Run("test run empty partition and loadPartition", func(t *testing.T) {
streaming, err := genSimpleReplicaWithGrowingSegment()
assert.NoError(t, err)
col, err := streaming.getCollectionByID(defaultCollectionID)
assert.NoError(t, err)
col.setLoadType(loadTypePartition)
err = streaming.removePartition(defaultPartitionID)
assert.NoError(t, err)
_, _, _, err = statisticStreaming(streaming,
defaultCollectionID,
[]UniqueID{defaultPartitionID},
defaultDMLChannel)
assert.Error(t, err)
})
t.Run("test no partitions in collection", func(t *testing.T) {
streaming, err := genSimpleReplicaWithGrowingSegment()
assert.NoError(t, err)
err = streaming.removePartition(defaultPartitionID)
assert.NoError(t, err)
res, _, _, err := statisticStreaming(streaming,
defaultCollectionID,
[]UniqueID{},
defaultDMLChannel)
assert.NoError(t, err)
assert.Equal(t, 0, len(res))
})
}

View File

@ -0,0 +1,76 @@
package querynode
import (
"fmt"
"sync"
"github.com/milvus-io/milvus/internal/log"
)
// statisticOnSegments performs statistic on listed segments
// all segment ids are validated before calling this function
func statisticOnSegments(replica ReplicaInterface, segType segmentType, segIDs []UniqueID) ([]map[string]interface{}, error) {
// results variables
searchResults := make([]map[string]interface{}, len(segIDs))
errs := make([]error, len(segIDs))
// calling segment search in goroutines
var wg sync.WaitGroup
for i, segID := range segIDs {
wg.Add(1)
go func(segID UniqueID, i int) {
defer wg.Done()
seg, err := replica.getSegmentByID(segID, segType)
if err != nil {
log.Error(err.Error()) // should not happen but still ignore it since the result is still correct
return
}
// record search time
//tr := timerecord.NewTimeRecorder("searchOnSegments")
count := seg.getRealCount()
if count < 0 {
errs[i] = fmt.Errorf("segment %d has nil ptr", segID)
}
errs[i] = err
searchResults[i] = map[string]interface{}{
"row_count": count,
}
// update metrics
//metrics.QueryNodeSQSegmentLatency.WithLabelValues(fmt.Sprint(Params.QueryNodeCfg.GetNodeID()),
// metrics.SearchLabel,
// metrics.SealedSegmentLabel).Observe(float64(tr.ElapseSpan().Milliseconds()))
}(segID, i)
}
wg.Wait()
for _, err := range errs {
if err != nil {
return nil, err
}
}
return searchResults, nil
}
// statistic will do statistics on the historical segments the target segments in historical.
// if segIDs is not specified, it will search on all the historical segments specified by partIDs.
// if segIDs is specified, it will only search on the segments specified by the segIDs.
// if partIDs is empty, it means all the partitions of the loaded collection or all the partitions loaded.
func statisticHistorical(replica ReplicaInterface, collID UniqueID, partIDs []UniqueID, segIDs []UniqueID) ([]map[string]interface{}, []UniqueID, []UniqueID, error) {
searchPartIDs, searchSegmentIDs, err := validateOnHistoricalReplica(replica, collID, partIDs, segIDs)
if err != nil {
return nil, searchSegmentIDs, searchPartIDs, err
}
searchResults, err := statisticOnSegments(replica, segmentTypeSealed, searchSegmentIDs)
return searchResults, searchPartIDs, searchSegmentIDs, err
}
// statisticStreaming will do statistics all the target segments in streaming
// if partIDs is empty, it means all the partitions of the loaded collection or all the partitions loaded.
func statisticStreaming(replica ReplicaInterface, collID UniqueID, partIDs []UniqueID, vChannel Channel) ([]map[string]interface{}, []UniqueID, []UniqueID, error) {
searchPartIDs, searchSegmentIDs, err := validateOnStreamReplica(replica, collID, partIDs, vChannel)
if err != nil {
return nil, searchSegmentIDs, searchPartIDs, err
}
searchResults, err := statisticOnSegments(replica, segmentTypeGrowing, searchSegmentIDs)
return searchResults, searchPartIDs, searchSegmentIDs, err
}

View File

@ -180,6 +180,8 @@ func (s *taskScheduler) tryEvictUnsolvedReadTask(headCount int) {
func (s *taskScheduler) scheduleReadTasks() {
defer s.wg.Done()
l := s.tSafeReplica.Watch()
defer l.Unregister()
for {
select {
case <-s.ctx.Done():
@ -210,7 +212,7 @@ func (s *taskScheduler) scheduleReadTasks() {
log.Warn(errMsg)
return
}
case <-s.tSafeReplica.Watch():
case <-l.On():
s.tryMergeReadTasks()
s.popAndAddToExecute()
}

View File

@ -404,7 +404,7 @@ func newSearchTask(ctx context.Context, src *querypb.SearchRequest) (*searchTask
id: src.Req.Base.GetMsgID(),
ts: src.Req.Base.GetTimestamp(),
},
DbID: src.Req.GetReqID(),
DbID: src.Req.GetDbID(),
CollectionID: src.Req.GetCollectionID(),
TravelTimestamp: src.Req.GetTravelTimestamp(),
GuaranteeTimestamp: src.Req.GetGuaranteeTimestamp(),

View File

@ -0,0 +1,158 @@
package querynode
import (
"context"
"errors"
"fmt"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/proto/querypb"
"github.com/milvus-io/milvus/internal/util/funcutil"
"github.com/milvus-io/milvus/internal/util/timerecord"
)
// not implement any task
type statistics struct {
id int64
ts Timestamp
ctx context.Context
qs *queryShard
scope querypb.DataScope
travelTimestamp Timestamp
guaranteeTimestamp Timestamp
timeoutTimestamp Timestamp
tr *timerecord.TimeRecorder
iReq *internalpb.GetStatisticsRequest
req *querypb.GetStatisticsRequest
Ret *internalpb.GetStatisticsResponse
waitCanDoFunc func(ctx context.Context) error
}
func (s *statistics) statisticOnStreaming() error {
// check ctx timeout
if !funcutil.CheckCtxValid(s.ctx) {
return errors.New("get statistics context timeout")
}
// check if collection has been released, check streaming since it's released first
_, err := s.qs.metaReplica.getCollectionByID(s.iReq.GetCollectionID())
if err != nil {
return err
}
s.qs.collection.RLock() // locks the collectionPtr
defer s.qs.collection.RUnlock()
if _, released := s.qs.collection.getReleaseTime(); released {
log.Debug("collection release before do statistics", zap.Int64("msgID", s.id),
zap.Int64("collectionID", s.iReq.GetCollectionID()))
return fmt.Errorf("statistic failed, collection has been released, collectionID = %d", s.iReq.GetCollectionID())
}
results, _, _, err := statisticStreaming(s.qs.metaReplica, s.iReq.GetCollectionID(), s.iReq.GetPartitionIDs(), s.req.GetDmlChannels()[0])
if err != nil {
log.Debug("failed to statistic on streaming data", zap.Int64("msgID", s.id),
zap.Int64("collectionID", s.iReq.GetCollectionID()), zap.Error(err))
return err
}
return s.reduceResults(results)
}
func (s *statistics) statisticOnHistorical() error {
// check ctx timeout
if !funcutil.CheckCtxValid(s.ctx) {
return errors.New("get statistics context timeout")
}
// check if collection has been released, check streaming since it's released first
_, err := s.qs.metaReplica.getCollectionByID(s.iReq.GetCollectionID())
if err != nil {
return err
}
s.qs.collection.RLock() // locks the collectionPtr
defer s.qs.collection.RUnlock()
if _, released := s.qs.collection.getReleaseTime(); released {
log.Debug("collection release before do statistics", zap.Int64("msgID", s.id),
zap.Int64("collectionID", s.iReq.GetCollectionID()))
return fmt.Errorf("statistic failed, collection has been released, collectionID = %d", s.iReq.GetCollectionID())
}
segmentIDs := s.req.GetSegmentIDs()
results, _, _, err := statisticHistorical(s.qs.metaReplica, s.iReq.GetCollectionID(), s.iReq.GetPartitionIDs(), segmentIDs)
if err != nil {
return err
}
return s.reduceResults(results)
}
func (s *statistics) Execute(ctx context.Context) error {
if err := s.waitCanDoFunc(ctx); err != nil {
return err
}
if s.scope == querypb.DataScope_Streaming {
return s.statisticOnStreaming()
} else if s.scope == querypb.DataScope_Historical {
return s.statisticOnHistorical()
}
return fmt.Errorf("statistics do not implement do statistic on all data scope")
}
func (s *statistics) reduceResults(results []map[string]interface{}) error {
mergedResults := map[string]interface{}{
"row_count": int64(0),
}
fieldMethod := map[string]func(interface{}) error{
"row_count": func(v interface{}) error {
count, ok := v.(int64)
if !ok {
return fmt.Errorf("invalid value type for row_count. expect int64, got %T", v)
}
mergedResults["row_count"] = mergedResults["row_count"].(int64) + count
return nil
},
}
for _, result := range results {
for k, v := range result {
fn, ok := fieldMethod[k]
if !ok {
return fmt.Errorf("unknown field %s", k)
}
if err := fn(v); err != nil {
return err
}
}
}
stringMap := make(map[string]string)
for k, v := range mergedResults {
stringMap[k] = fmt.Sprint(v)
}
s.Ret = &internalpb.GetStatisticsResponse{
Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success},
Stats: funcutil.Map2KeyValuePair(stringMap),
}
return nil
}
func newStatistics(ctx context.Context, src *querypb.GetStatisticsRequest, scope querypb.DataScope, qs *queryShard, waitCanDo func(ctx context.Context) error) *statistics {
target := &statistics{
ctx: ctx,
id: src.Req.Base.GetMsgID(),
ts: src.Req.Base.GetTimestamp(),
scope: scope,
qs: qs,
travelTimestamp: src.Req.GetTravelTimestamp(),
guaranteeTimestamp: src.Req.GetGuaranteeTimestamp(),
timeoutTimestamp: src.Req.GetTimeoutTimestamp(),
tr: timerecord.NewTimeRecorder("statistics"),
iReq: src.Req,
req: src,
waitCanDoFunc: waitCanDo,
}
return target
}

View File

@ -32,7 +32,8 @@ type TSafeReplicaInterface interface {
setTSafe(vChannel Channel, timestamp Timestamp) error
addTSafe(vChannel Channel)
removeTSafe(vChannel Channel)
Watch() <-chan struct{}
Watch() Listener
WatchChannel(channel Channel) Listener
}
type tSafe struct {
@ -75,13 +76,31 @@ func newTSafe(channel Channel) *tSafe {
// tSafeReplica implements `TSafeReplicaInterface` interface.
type tSafeReplica struct {
mu sync.Mutex // guards tSafes
tSafes map[Channel]*tSafe // map[DMLChannel|deltaChannel]*tSafe
notifyChan chan struct{}
mu sync.Mutex // guards tSafes
tSafes map[Channel]*tSafe // map[DMLChannel|deltaChannel]*tSafe
listeners map[Channel][]*listener // map[DMLChannel|deltaChannel][]*listener, key "" means all channels.
}
func (t *tSafeReplica) Watch() <-chan struct{} {
return t.notifyChan
// since notifyAll called by setTSafe, no need to lock
func (t *tSafeReplica) notifyAll(channel Channel) {
for _, l := range t.listeners[""] {
l.nonBlockingNotify()
}
for _, l := range t.listeners[channel] {
l.nonBlockingNotify()
}
}
func (t *tSafeReplica) Watch() Listener {
return t.WatchChannel("")
}
func (t *tSafeReplica) WatchChannel(channel Channel) Listener {
t.mu.Lock()
defer t.mu.Unlock()
l := newListener(t, channel)
t.listeners[channel] = append(t.listeners[channel], l)
return l
}
func (t *tSafeReplica) getTSafe(vChannel Channel) (Timestamp, error) {
@ -102,11 +121,7 @@ func (t *tSafeReplica) setTSafe(vChannel Channel, timestamp Timestamp) error {
return fmt.Errorf("set tSafe failed, err = %w", err)
}
ts.set(timestamp)
select {
case t.notifyChan <- struct{}{}:
default:
}
t.notifyAll(vChannel)
return nil
}
@ -136,13 +151,68 @@ func (t *tSafeReplica) removeTSafe(vChannel Channel) {
if ok {
tsafe.close()
}
for _, l := range t.listeners[vChannel] {
l.unregister()
}
delete(t.tSafes, vChannel)
delete(t.listeners, vChannel)
}
func newTSafeReplica() TSafeReplicaInterface {
var replica TSafeReplicaInterface = &tSafeReplica{
tSafes: make(map[string]*tSafe),
notifyChan: make(chan struct{}, 1),
tSafes: make(map[string]*tSafe),
listeners: make(map[string][]*listener),
}
return replica
}
type Listener interface {
On() <-chan struct{}
Unregister()
}
type listener struct {
tsafe *tSafeReplica
channel Channel
ch chan struct{}
}
func (l *listener) On() <-chan struct{} {
return l.ch
}
func (l *listener) Unregister() {
l.tsafe.mu.Lock()
defer l.tsafe.mu.Unlock()
l.unregister()
}
// unregister remove the listener from the tSafeReplica without lock
func (l *listener) unregister() {
for i, listen := range l.tsafe.listeners[l.channel] {
if l == listen {
close(l.ch)
l.tsafe.listeners[l.channel] = append(l.tsafe.listeners[l.channel][:i], l.tsafe.listeners[l.channel][i+1:]...)
break
}
}
}
func (l *listener) nonBlockingNotify() {
select {
case l.ch <- struct{}{}:
default:
}
}
//func (l *listener) blockingNotify() {
// l.ch <- struct{}{}
//}
func newListener(tsafe *tSafeReplica, channel Channel) *listener {
return &listener{
tsafe: tsafe,
channel: channel,
ch: make(chan struct{}, 1),
}
}

View File

@ -49,4 +49,35 @@ func TestTSafeReplica(t *testing.T) {
err = replica.setTSafe(defaultDMLChannel, Timestamp(1000))
assert.Error(t, err)
})
t.Run("test listener", func(t *testing.T) {
replica := newTSafeReplica()
replica.addTSafe(defaultDMLChannel)
globalWatcher := replica.Watch()
channelWatcher := replica.WatchChannel(defaultDMLChannel)
timestamp := Timestamp(1000)
err := replica.setTSafe(defaultDMLChannel, timestamp)
assert.NoError(t, err)
select {
case <-globalWatcher.On():
default:
assert.Fail(t, "global watcher should be triggered")
}
select {
case <-channelWatcher.On():
default:
assert.Fail(t, "channel watcher should be triggered")
}
globalWatcher.Unregister()
channelWatcher.Unregister()
inst := replica.(*tSafeReplica)
assert.Len(t, inst.listeners[""], 0)
assert.Len(t, inst.listeners[defaultDMLChannel], 0)
})
}

View File

@ -1219,6 +1219,7 @@ type QueryNode interface {
ReleaseSegments(ctx context.Context, req *querypb.ReleaseSegmentsRequest) (*commonpb.Status, error)
GetSegmentInfo(ctx context.Context, req *querypb.GetSegmentInfoRequest) (*querypb.GetSegmentInfoResponse, error)
GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error)
Search(ctx context.Context, req *querypb.SearchRequest) (*internalpb.SearchResults, error)
Query(ctx context.Context, req *querypb.QueryRequest) (*internalpb.RetrieveResults, error)
SyncReplicaSegments(ctx context.Context, req *querypb.SyncReplicaSegmentsRequest) (*commonpb.Status, error)

View File

@ -0,0 +1,19 @@
package funcutil
import "fmt"
func MapReduce(results []map[string]string, method map[string]func(string) error) error {
// TODO: use generic type to reconstruct map[string]string -> [T any] map[string]T
for _, result := range results {
for k, v := range result {
fn, ok := method[k]
if !ok {
return fmt.Errorf("unknown field %s", k)
}
if err := fn(v); err != nil {
return err
}
}
}
return nil
}

View File

@ -33,6 +33,10 @@ type GrpcQueryNodeClient struct {
Err error
}
func (m *GrpcQueryNodeClient) GetStatistics(ctx context.Context, in *querypb.GetStatisticsRequest, opts ...grpc.CallOption) (*internalpb.GetStatisticsResponse, error) {
return &internalpb.GetStatisticsResponse{}, m.Err
}
func (m *GrpcQueryNodeClient) GetComponentStates(ctx context.Context, in *internalpb.GetComponentStatesRequest, opts ...grpc.CallOption) (*internalpb.ComponentStates, error) {
return &internalpb.ComponentStates{}, m.Err
}

View File

@ -33,6 +33,10 @@ type QueryNodeClient struct {
Err error
}
func (q QueryNodeClient) GetStatistics(ctx context.Context, req *querypb.GetStatisticsRequest) (*internalpb.GetStatisticsResponse, error) {
return q.grpcClient.GetStatistics(ctx, req)
}
func (q QueryNodeClient) Init() error {
return nil
}