提交 b0471a7e 编写于 作者: G groot

add new query interface for specified files


Former-commit-id: 5679e6c73f5475b04ce6db79de197cfd5d3e5499
上级 cd2f7d57
......@@ -34,6 +34,7 @@ Please mark all change in change log and use the ticket from JIRA.
- MS-81 - fix faiss ptx issue; change cuda gencode
- MS-84 - cmake: add arrow, jemalloc and jsoncons third party; default build option OFF
- MS-85 - add NetIO metric
- MS-96 - add new query interface for specified files
## Task
- MS-74 - Change README.md in cpp
......
......@@ -38,6 +38,10 @@ public:
virtual Status Query(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results) = 0;
virtual Status Query(const std::string& table_id, const std::vector<std::string>& file_ids,
uint64_t k, uint64_t nq, const float* vectors,
const meta::DatesT& dates, QueryResults& results) = 0;
virtual Status Size(uint64_t& result) = 0;
virtual Status DropAll() = 0;
......
......@@ -216,10 +216,41 @@ Status DBImpl::Query(const std::string& table_id, uint64_t k, uint64_t nq,
#if 0
return QuerySync(table_id, k, nq, vectors, dates, results);
#else
return QueryAsync(table_id, k, nq, vectors, dates, results);
//get all table files from table
meta::DatePartionedTableFilesSchema files;
auto status = pMeta_->FilesToSearch(table_id, dates, files);
if (!status.ok()) { return status; }
meta::TableFilesSchema file_id_array;
for (auto &day_files : files) {
for (auto &file : day_files.second) {
file_id_array.push_back(file);
}
}
return QueryAsync(table_id, file_id_array, k, nq, vectors, dates, results);
#endif
}
Status DBImpl::Query(const std::string& table_id, const std::vector<std::string>& file_ids,
uint64_t k, uint64_t nq, const float* vectors,
const meta::DatesT& dates, QueryResults& results) {
//get specified files
meta::TableFilesSchema files_array;
for (auto &id : file_ids) {
meta::TableFileSchema table_file;
table_file.table_id_ = id;
auto status = pMeta_->GetTableFile(table_file);
if (!status.ok()) {
return status;
}
files_array.emplace_back(table_file);
}
return QueryAsync(table_id, files_array, k, nq, vectors, dates, results);
}
Status DBImpl::QuerySync(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results) {
meta::DatePartionedTableFilesSchema files;
......@@ -359,23 +390,16 @@ Status DBImpl::QuerySync(const std::string& table_id, uint64_t k, uint64_t nq,
return Status::OK();
}
Status DBImpl::QueryAsync(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results) {
Status DBImpl::QueryAsync(const std::string& table_id, const meta::TableFilesSchema& files,
uint64_t k, uint64_t nq, const float* vectors,
const meta::DatesT& dates, QueryResults& results) {
//step 1: get files to search
meta::DatePartionedTableFilesSchema files;
auto status = pMeta_->FilesToSearch(table_id, dates, files);
if (!status.ok()) { return status; }
ENGINE_LOG_DEBUG << "Search DateT Size=" << files.size();
SearchContextPtr context = std::make_shared<SearchContext>(k, nq, vectors);
for (auto &day_files : files) {
for (auto &file : day_files.second) {
TableFileSchemaPtr file_ptr = std::make_shared<meta::TableFileSchema>(file);
context->AddIndexFile(file_ptr);
}
for (auto &file : files) {
TableFileSchemaPtr file_ptr = std::make_shared<meta::TableFileSchema>(file);
context->AddIndexFile(file_ptr);
}
//step 2: put search task to scheduler
......
......@@ -48,6 +48,10 @@ public:
virtual Status Query(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results) override;
virtual Status Query(const std::string& table_id, const std::vector<std::string>& file_ids,
uint64_t k, uint64_t nq, const float* vectors,
const meta::DatesT& dates, QueryResults& results) override;
virtual Status DropAll() override;
virtual Status Size(uint64_t& result) override;
......@@ -58,8 +62,9 @@ private:
Status QuerySync(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results);
Status QueryAsync(const std::string& table_id, uint64_t k, uint64_t nq,
const float* vectors, const meta::DatesT& dates, QueryResults& results);
Status QueryAsync(const std::string& table_id, const meta::TableFilesSchema& files,
uint64_t k, uint64_t nq, const float* vectors,
const meta::DatesT& dates, QueryResults& results);
void BackgroundBuildIndex();
......
......@@ -32,19 +32,32 @@ RequestHandler::DeleteTable(const std::string &table_name) {
void
RequestHandler::AddVector(std::vector<int64_t> &_return,
const std::string &table_name,
const std::vector<thrift::RowRecord> &record_array) {
const std::string &table_name,
const std::vector<thrift::RowRecord> &record_array) {
BaseTaskPtr task_ptr = AddVectorTask::Create(table_name, record_array, _return);
RequestScheduler::ExecTask(task_ptr);
}
void
RequestHandler::SearchVector(std::vector<thrift::TopKQueryResult> & _return,
const std::string& table_name,
const std::vector<thrift::RowRecord> & query_record_array,
const std::vector<thrift::Range> & query_range_array,
const int64_t topk) {
BaseTaskPtr task_ptr = SearchVectorTask::Create(table_name, query_record_array, query_range_array, topk, _return);
RequestHandler::SearchVector(std::vector<thrift::TopKQueryResult> &_return,
const std::string &table_name,
const std::vector<thrift::RowRecord> &query_record_array,
const std::vector<thrift::Range> &query_range_array,
const int64_t topk) {
BaseTaskPtr task_ptr = SearchVectorTask::Create(table_name, std::vector<std::string>(), query_record_array,
query_range_array, topk, _return);
RequestScheduler::ExecTask(task_ptr);
}
void
RequestHandler::SearchVectorInFiles(std::vector<::milvus::thrift::TopKQueryResult> &_return,
const std::string& table_name,
const std::vector<std::string> &file_id_array,
const std::vector<::milvus::thrift::RowRecord> &query_record_array,
const std::vector<::milvus::thrift::Range> &query_range_array,
const int64_t topk) {
BaseTaskPtr task_ptr = SearchVectorTask::Create(table_name, file_id_array, query_record_array,
query_range_array, topk, _return);
RequestScheduler::ExecTask(task_ptr);
}
......
......@@ -82,6 +82,30 @@ public:
const std::vector<::milvus::thrift::Range> & query_range_array,
const int64_t topk);
/**
* @brief Internal use query interface
*
* This method is used to query vector in specified files.
*
* @param file_id_array, specified files id array, queried.
* @param query_record_array, all vector are going to be queried.
* @param query_range_array, optional ranges for conditional search. If not specified, search whole table
* @param topk, how many similarity vectors will be searched.
*
* @return query result array.
*
* @param file_id_array
* @param query_record_array
* @param query_range_array
* @param topk
*/
virtual void SearchVectorInFiles(std::vector<::milvus::thrift::TopKQueryResult> & _return,
const std::string& table_name,
const std::vector<std::string> & file_id_array,
const std::vector<::milvus::thrift::RowRecord> & query_record_array,
const std::vector<::milvus::thrift::Range> & query_range_array,
const int64_t topk);
/**
* @brief Get table schema
*
......
......@@ -447,26 +447,29 @@ ServerError AddVectorTask::OnExecute() {
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SearchVectorTask::SearchVectorTask(const std::string& table_name,
const std::vector<thrift::RowRecord> & query_record_array,
const std::vector<thrift::Range> & query_range_array,
SearchVectorTask::SearchVectorTask(const std::string &table_name,
const std::vector<std::string>& file_id_array,
const std::vector<thrift::RowRecord> &query_record_array,
const std::vector<thrift::Range> &query_range_array,
const int64_t top_k,
std::vector<thrift::TopKQueryResult>& result_array)
: BaseTask(DQL_TASK_GROUP),
table_name_(table_name),
record_array_(query_record_array),
range_array_(query_range_array),
top_k_(top_k),
result_array_(result_array) {
std::vector<thrift::TopKQueryResult> &result_array)
: BaseTask(DQL_TASK_GROUP),
table_name_(table_name),
file_id_array_(file_id_array),
record_array_(query_record_array),
range_array_(query_range_array),
top_k_(top_k),
result_array_(result_array) {
}
BaseTaskPtr SearchVectorTask::Create(const std::string& table_name,
const std::vector<std::string>& file_id_array,
const std::vector<thrift::RowRecord> & query_record_array,
const std::vector<thrift::Range> & query_range_array,
const int64_t top_k,
std::vector<thrift::TopKQueryResult>& result_array) {
return std::shared_ptr<BaseTask>(new SearchVectorTask(table_name,
return std::shared_ptr<BaseTask>(new SearchVectorTask(table_name, file_id_array,
query_record_array, query_range_array, top_k, result_array));
}
......@@ -523,7 +526,13 @@ ServerError SearchVectorTask::OnExecute() {
//step 4: search vectors
engine::QueryResults results;
uint64_t record_count = (uint64_t)record_array_.size();
stat = DB()->Query(table_name_, (size_t)top_k_, record_count, vec_f.data(), dates, results);
if(file_id_array_.empty()) {
stat = DB()->Query(table_name_, (size_t) top_k_, record_count, vec_f.data(), dates, results);
} else {
stat = DB()->Query(table_name_, file_id_array_, (size_t) top_k_, record_count, vec_f.data(), dates, results);
}
rc.Record("search vectors from engine");
if(!stat.ok()) {
SERVER_LOG_ERROR << "Engine failed: " << stat.ToString();
......@@ -555,6 +564,7 @@ ServerError SearchVectorTask::OnExecute() {
}
rc.Record("construct result");
rc.Elapse("totally cost");
} catch (std::exception& ex) {
error_code_ = SERVER_UNEXPECTED_ERROR;
error_msg_ = ex.what();
......
......@@ -102,6 +102,7 @@ private:
class SearchVectorTask : public BaseTask {
public:
static BaseTaskPtr Create(const std::string& table_name,
const std::vector<std::string>& file_id_array,
const std::vector<::milvus::thrift::RowRecord> & query_record_array,
const std::vector<::milvus::thrift::Range> & query_range_array,
const int64_t top_k,
......@@ -109,6 +110,7 @@ public:
protected:
SearchVectorTask(const std::string& table_name,
const std::vector<std::string>& file_id_array,
const std::vector<::milvus::thrift::RowRecord> & query_record_array,
const std::vector<::milvus::thrift::Range> & query_range_array,
const int64_t top_k,
......@@ -118,6 +120,7 @@ protected:
private:
std::string table_name_;
std::vector<std::string> file_id_array_;
int64_t top_k_;
const std::vector<::milvus::thrift::RowRecord>& record_array_;
const std::vector<::milvus::thrift::Range>& range_array_;
......
......@@ -1009,6 +1009,393 @@ uint32_t MilvusService_SearchVector_presult::read(::apache::thrift::protocol::TP
}
MilvusService_SearchVectorInFiles_args::~MilvusService_SearchVectorInFiles_args() throw() {
}
uint32_t MilvusService_SearchVectorInFiles_args::read(::apache::thrift::protocol::TProtocol* iprot) {
::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
uint32_t xfer = 0;
std::string fname;
::apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
using ::apache::thrift::protocol::TProtocolException;
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == ::apache::thrift::protocol::T_STOP) {
break;
}
switch (fid)
{
case 2:
if (ftype == ::apache::thrift::protocol::T_STRING) {
xfer += iprot->readString(this->table_name);
this->__isset.table_name = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 3:
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
this->file_id_array.clear();
uint32_t _size62;
::apache::thrift::protocol::TType _etype65;
xfer += iprot->readListBegin(_etype65, _size62);
this->file_id_array.resize(_size62);
uint32_t _i66;
for (_i66 = 0; _i66 < _size62; ++_i66)
{
xfer += iprot->readString(this->file_id_array[_i66]);
}
xfer += iprot->readListEnd();
}
this->__isset.file_id_array = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 4:
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
this->query_record_array.clear();
uint32_t _size67;
::apache::thrift::protocol::TType _etype70;
xfer += iprot->readListBegin(_etype70, _size67);
this->query_record_array.resize(_size67);
uint32_t _i71;
for (_i71 = 0; _i71 < _size67; ++_i71)
{
xfer += this->query_record_array[_i71].read(iprot);
}
xfer += iprot->readListEnd();
}
this->__isset.query_record_array = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 5:
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
this->query_range_array.clear();
uint32_t _size72;
::apache::thrift::protocol::TType _etype75;
xfer += iprot->readListBegin(_etype75, _size72);
this->query_range_array.resize(_size72);
uint32_t _i76;
for (_i76 = 0; _i76 < _size72; ++_i76)
{
xfer += this->query_range_array[_i76].read(iprot);
}
xfer += iprot->readListEnd();
}
this->__isset.query_range_array = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 6:
if (ftype == ::apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->topk);
this->__isset.topk = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
uint32_t MilvusService_SearchVectorInFiles_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
xfer += oprot->writeStructBegin("MilvusService_SearchVectorInFiles_args");
xfer += oprot->writeFieldBegin("table_name", ::apache::thrift::protocol::T_STRING, 2);
xfer += oprot->writeString(this->table_name);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("file_id_array", ::apache::thrift::protocol::T_LIST, 3);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->file_id_array.size()));
std::vector<std::string> ::const_iterator _iter77;
for (_iter77 = this->file_id_array.begin(); _iter77 != this->file_id_array.end(); ++_iter77)
{
xfer += oprot->writeString((*_iter77));
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("query_record_array", ::apache::thrift::protocol::T_LIST, 4);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->query_record_array.size()));
std::vector<RowRecord> ::const_iterator _iter78;
for (_iter78 = this->query_record_array.begin(); _iter78 != this->query_record_array.end(); ++_iter78)
{
xfer += (*_iter78).write(oprot);
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("query_range_array", ::apache::thrift::protocol::T_LIST, 5);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->query_range_array.size()));
std::vector<Range> ::const_iterator _iter79;
for (_iter79 = this->query_range_array.begin(); _iter79 != this->query_range_array.end(); ++_iter79)
{
xfer += (*_iter79).write(oprot);
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("topk", ::apache::thrift::protocol::T_I64, 6);
xfer += oprot->writeI64(this->topk);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
MilvusService_SearchVectorInFiles_pargs::~MilvusService_SearchVectorInFiles_pargs() throw() {
}
uint32_t MilvusService_SearchVectorInFiles_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
xfer += oprot->writeStructBegin("MilvusService_SearchVectorInFiles_pargs");
xfer += oprot->writeFieldBegin("table_name", ::apache::thrift::protocol::T_STRING, 2);
xfer += oprot->writeString((*(this->table_name)));
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("file_id_array", ::apache::thrift::protocol::T_LIST, 3);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->file_id_array)).size()));
std::vector<std::string> ::const_iterator _iter80;
for (_iter80 = (*(this->file_id_array)).begin(); _iter80 != (*(this->file_id_array)).end(); ++_iter80)
{
xfer += oprot->writeString((*_iter80));
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("query_record_array", ::apache::thrift::protocol::T_LIST, 4);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->query_record_array)).size()));
std::vector<RowRecord> ::const_iterator _iter81;
for (_iter81 = (*(this->query_record_array)).begin(); _iter81 != (*(this->query_record_array)).end(); ++_iter81)
{
xfer += (*_iter81).write(oprot);
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("query_range_array", ::apache::thrift::protocol::T_LIST, 5);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->query_range_array)).size()));
std::vector<Range> ::const_iterator _iter82;
for (_iter82 = (*(this->query_range_array)).begin(); _iter82 != (*(this->query_range_array)).end(); ++_iter82)
{
xfer += (*_iter82).write(oprot);
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("topk", ::apache::thrift::protocol::T_I64, 6);
xfer += oprot->writeI64((*(this->topk)));
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
MilvusService_SearchVectorInFiles_result::~MilvusService_SearchVectorInFiles_result() throw() {
}
uint32_t MilvusService_SearchVectorInFiles_result::read(::apache::thrift::protocol::TProtocol* iprot) {
::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
uint32_t xfer = 0;
std::string fname;
::apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
using ::apache::thrift::protocol::TProtocolException;
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == ::apache::thrift::protocol::T_STOP) {
break;
}
switch (fid)
{
case 0:
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
this->success.clear();
uint32_t _size83;
::apache::thrift::protocol::TType _etype86;
xfer += iprot->readListBegin(_etype86, _size83);
this->success.resize(_size83);
uint32_t _i87;
for (_i87 = 0; _i87 < _size83; ++_i87)
{
xfer += this->success[_i87].read(iprot);
}
xfer += iprot->readListEnd();
}
this->__isset.success = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 1:
if (ftype == ::apache::thrift::protocol::T_STRUCT) {
xfer += this->e.read(iprot);
this->__isset.e = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
uint32_t MilvusService_SearchVectorInFiles_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
xfer += oprot->writeStructBegin("MilvusService_SearchVectorInFiles_result");
if (this->__isset.success) {
xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
std::vector<TopKQueryResult> ::const_iterator _iter88;
for (_iter88 = this->success.begin(); _iter88 != this->success.end(); ++_iter88)
{
xfer += (*_iter88).write(oprot);
}
xfer += oprot->writeListEnd();
}
xfer += oprot->writeFieldEnd();
} else if (this->__isset.e) {
xfer += oprot->writeFieldBegin("e", ::apache::thrift::protocol::T_STRUCT, 1);
xfer += this->e.write(oprot);
xfer += oprot->writeFieldEnd();
}
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
MilvusService_SearchVectorInFiles_presult::~MilvusService_SearchVectorInFiles_presult() throw() {
}
uint32_t MilvusService_SearchVectorInFiles_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
uint32_t xfer = 0;
std::string fname;
::apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
using ::apache::thrift::protocol::TProtocolException;
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == ::apache::thrift::protocol::T_STOP) {
break;
}
switch (fid)
{
case 0:
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
(*(this->success)).clear();
uint32_t _size89;
::apache::thrift::protocol::TType _etype92;
xfer += iprot->readListBegin(_etype92, _size89);
(*(this->success)).resize(_size89);
uint32_t _i93;
for (_i93 = 0; _i93 < _size89; ++_i93)
{
xfer += (*(this->success))[_i93].read(iprot);
}
xfer += iprot->readListEnd();
}
this->__isset.success = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 1:
if (ftype == ::apache::thrift::protocol::T_STRUCT) {
xfer += this->e.read(iprot);
this->__isset.e = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
MilvusService_DescribeTable_args::~MilvusService_DescribeTable_args() throw() {
}
......@@ -1510,14 +1897,14 @@ uint32_t MilvusService_ShowTables_result::read(::apache::thrift::protocol::TProt
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
this->success.clear();
uint32_t _size62;
::apache::thrift::protocol::TType _etype65;
xfer += iprot->readListBegin(_etype65, _size62);
this->success.resize(_size62);
uint32_t _i66;
for (_i66 = 0; _i66 < _size62; ++_i66)
uint32_t _size94;
::apache::thrift::protocol::TType _etype97;
xfer += iprot->readListBegin(_etype97, _size94);
this->success.resize(_size94);
uint32_t _i98;
for (_i98 = 0; _i98 < _size94; ++_i98)
{
xfer += iprot->readString(this->success[_i66]);
xfer += iprot->readString(this->success[_i98]);
}
xfer += iprot->readListEnd();
}
......@@ -1556,10 +1943,10 @@ uint32_t MilvusService_ShowTables_result::write(::apache::thrift::protocol::TPro
xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
{
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
std::vector<std::string> ::const_iterator _iter67;
for (_iter67 = this->success.begin(); _iter67 != this->success.end(); ++_iter67)
std::vector<std::string> ::const_iterator _iter99;
for (_iter99 = this->success.begin(); _iter99 != this->success.end(); ++_iter99)
{
xfer += oprot->writeString((*_iter67));
xfer += oprot->writeString((*_iter99));
}
xfer += oprot->writeListEnd();
}
......@@ -1604,14 +1991,14 @@ uint32_t MilvusService_ShowTables_presult::read(::apache::thrift::protocol::TPro
if (ftype == ::apache::thrift::protocol::T_LIST) {
{
(*(this->success)).clear();
uint32_t _size68;
::apache::thrift::protocol::TType _etype71;
xfer += iprot->readListBegin(_etype71, _size68);
(*(this->success)).resize(_size68);
uint32_t _i72;
for (_i72 = 0; _i72 < _size68; ++_i72)
uint32_t _size100;
::apache::thrift::protocol::TType _etype103;
xfer += iprot->readListBegin(_etype103, _size100);
(*(this->success)).resize(_size100);
uint32_t _i104;
for (_i104 = 0; _i104 < _size100; ++_i104)
{
xfer += iprot->readString((*(this->success))[_i72]);
xfer += iprot->readString((*(this->success))[_i104]);
}
xfer += iprot->readListEnd();
}
......@@ -2085,6 +2472,71 @@ void MilvusServiceClient::recv_SearchVector(std::vector<TopKQueryResult> & _retu
throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "SearchVector failed: unknown result");
}
void MilvusServiceClient::SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk)
{
send_SearchVectorInFiles(table_name, file_id_array, query_record_array, query_range_array, topk);
recv_SearchVectorInFiles(_return);
}
void MilvusServiceClient::send_SearchVectorInFiles(const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk)
{
int32_t cseqid = 0;
oprot_->writeMessageBegin("SearchVectorInFiles", ::apache::thrift::protocol::T_CALL, cseqid);
MilvusService_SearchVectorInFiles_pargs args;
args.table_name = &table_name;
args.file_id_array = &file_id_array;
args.query_record_array = &query_record_array;
args.query_range_array = &query_range_array;
args.topk = &topk;
args.write(oprot_);
oprot_->writeMessageEnd();
oprot_->getTransport()->writeEnd();
oprot_->getTransport()->flush();
}
void MilvusServiceClient::recv_SearchVectorInFiles(std::vector<TopKQueryResult> & _return)
{
int32_t rseqid = 0;
std::string fname;
::apache::thrift::protocol::TMessageType mtype;
iprot_->readMessageBegin(fname, mtype, rseqid);
if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
::apache::thrift::TApplicationException x;
x.read(iprot_);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
throw x;
}
if (mtype != ::apache::thrift::protocol::T_REPLY) {
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
}
if (fname.compare("SearchVectorInFiles") != 0) {
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
}
MilvusService_SearchVectorInFiles_presult result;
result.success = &_return;
result.read(iprot_);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
if (result.__isset.success) {
// _return pointer has now been filled
return;
}
if (result.__isset.e) {
throw result.e;
}
throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "SearchVectorInFiles failed: unknown result");
}
void MilvusServiceClient::DescribeTable(TableSchema& _return, const std::string& table_name)
{
send_DescribeTable(table_name);
......@@ -2573,6 +3025,63 @@ void MilvusServiceProcessor::process_SearchVector(int32_t seqid, ::apache::thrif
}
}
void MilvusServiceProcessor::process_SearchVectorInFiles(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
void* ctx = NULL;
if (this->eventHandler_.get() != NULL) {
ctx = this->eventHandler_->getContext("MilvusService.SearchVectorInFiles", callContext);
}
::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "MilvusService.SearchVectorInFiles");
if (this->eventHandler_.get() != NULL) {
this->eventHandler_->preRead(ctx, "MilvusService.SearchVectorInFiles");
}
MilvusService_SearchVectorInFiles_args args;
args.read(iprot);
iprot->readMessageEnd();
uint32_t bytes = iprot->getTransport()->readEnd();
if (this->eventHandler_.get() != NULL) {
this->eventHandler_->postRead(ctx, "MilvusService.SearchVectorInFiles", bytes);
}
MilvusService_SearchVectorInFiles_result result;
try {
iface_->SearchVectorInFiles(result.success, args.table_name, args.file_id_array, args.query_record_array, args.query_range_array, args.topk);
result.__isset.success = true;
} catch (Exception &e) {
result.e = e;
result.__isset.e = true;
} catch (const std::exception& e) {
if (this->eventHandler_.get() != NULL) {
this->eventHandler_->handlerError(ctx, "MilvusService.SearchVectorInFiles");
}
::apache::thrift::TApplicationException x(e.what());
oprot->writeMessageBegin("SearchVectorInFiles", ::apache::thrift::protocol::T_EXCEPTION, seqid);
x.write(oprot);
oprot->writeMessageEnd();
oprot->getTransport()->writeEnd();
oprot->getTransport()->flush();
return;
}
if (this->eventHandler_.get() != NULL) {
this->eventHandler_->preWrite(ctx, "MilvusService.SearchVectorInFiles");
}
oprot->writeMessageBegin("SearchVectorInFiles", ::apache::thrift::protocol::T_REPLY, seqid);
result.write(oprot);
oprot->writeMessageEnd();
bytes = oprot->getTransport()->writeEnd();
oprot->getTransport()->flush();
if (this->eventHandler_.get() != NULL) {
this->eventHandler_->postWrite(ctx, "MilvusService.SearchVectorInFiles", bytes);
}
}
void MilvusServiceProcessor::process_DescribeTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
void* ctx = NULL;
......@@ -3152,6 +3661,98 @@ void MilvusServiceConcurrentClient::recv_SearchVector(std::vector<TopKQueryResul
} // end while(true)
}
void MilvusServiceConcurrentClient::SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk)
{
int32_t seqid = send_SearchVectorInFiles(table_name, file_id_array, query_record_array, query_range_array, topk);
recv_SearchVectorInFiles(_return, seqid);
}
int32_t MilvusServiceConcurrentClient::send_SearchVectorInFiles(const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk)
{
int32_t cseqid = this->sync_.generateSeqId();
::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
oprot_->writeMessageBegin("SearchVectorInFiles", ::apache::thrift::protocol::T_CALL, cseqid);
MilvusService_SearchVectorInFiles_pargs args;
args.table_name = &table_name;
args.file_id_array = &file_id_array;
args.query_record_array = &query_record_array;
args.query_range_array = &query_range_array;
args.topk = &topk;
args.write(oprot_);
oprot_->writeMessageEnd();
oprot_->getTransport()->writeEnd();
oprot_->getTransport()->flush();
sentry.commit();
return cseqid;
}
void MilvusServiceConcurrentClient::recv_SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const int32_t seqid)
{
int32_t rseqid = 0;
std::string fname;
::apache::thrift::protocol::TMessageType mtype;
// the read mutex gets dropped and reacquired as part of waitForWork()
// The destructor of this sentry wakes up other clients
::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
while(true) {
if(!this->sync_.getPending(fname, mtype, rseqid)) {
iprot_->readMessageBegin(fname, mtype, rseqid);
}
if(seqid == rseqid) {
if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
::apache::thrift::TApplicationException x;
x.read(iprot_);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
sentry.commit();
throw x;
}
if (mtype != ::apache::thrift::protocol::T_REPLY) {
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
}
if (fname.compare("SearchVectorInFiles") != 0) {
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
// in a bad state, don't commit
using ::apache::thrift::protocol::TProtocolException;
throw TProtocolException(TProtocolException::INVALID_DATA);
}
MilvusService_SearchVectorInFiles_presult result;
result.success = &_return;
result.read(iprot_);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
if (result.__isset.success) {
// _return pointer has now been filled
sentry.commit();
return;
}
if (result.__isset.e) {
sentry.commit();
throw result.e;
}
// in a bad state, don't commit
throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "SearchVectorInFiles failed: unknown result");
}
// seqid != rseqid
this->sync_.updatePending(fname, mtype, rseqid);
// this will temporarily unlock the readMutex, and let other clients get work done
this->sync_.waitForWork(seqid);
} // end while(true)
}
void MilvusServiceConcurrentClient::DescribeTable(TableSchema& _return, const std::string& table_name)
{
int32_t seqid = send_DescribeTable(table_name);
......
......@@ -80,6 +80,26 @@ class MilvusServiceIf {
*/
virtual void SearchVector(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk) = 0;
/**
* @brief Internal use query interface
*
* This method is used to query vector in specified files.
*
* @param file_id_array, specified files id array, queried.
* @param query_record_array, all vector are going to be queried.
* @param query_range_array, optional ranges for conditional search. If not specified, search whole table
* @param topk, how many similarity vectors will be searched.
*
* @return query result array.
*
* @param table_name
* @param file_id_array
* @param query_record_array
* @param query_range_array
* @param topk
*/
virtual void SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk) = 0;
/**
* @brief Get table schema
*
......@@ -167,6 +187,9 @@ class MilvusServiceNull : virtual public MilvusServiceIf {
void SearchVector(std::vector<TopKQueryResult> & /* _return */, const std::string& /* table_name */, const std::vector<RowRecord> & /* query_record_array */, const std::vector<Range> & /* query_range_array */, const int64_t /* topk */) {
return;
}
void SearchVectorInFiles(std::vector<TopKQueryResult> & /* _return */, const std::string& /* table_name */, const std::vector<std::string> & /* file_id_array */, const std::vector<RowRecord> & /* query_record_array */, const std::vector<Range> & /* query_range_array */, const int64_t /* topk */) {
return;
}
void DescribeTable(TableSchema& /* _return */, const std::string& /* table_name */) {
return;
}
......@@ -642,6 +665,146 @@ class MilvusService_SearchVector_presult {
};
typedef struct _MilvusService_SearchVectorInFiles_args__isset {
_MilvusService_SearchVectorInFiles_args__isset() : table_name(false), file_id_array(false), query_record_array(false), query_range_array(false), topk(false) {}
bool table_name :1;
bool file_id_array :1;
bool query_record_array :1;
bool query_range_array :1;
bool topk :1;
} _MilvusService_SearchVectorInFiles_args__isset;
class MilvusService_SearchVectorInFiles_args {
public:
MilvusService_SearchVectorInFiles_args(const MilvusService_SearchVectorInFiles_args&);
MilvusService_SearchVectorInFiles_args& operator=(const MilvusService_SearchVectorInFiles_args&);
MilvusService_SearchVectorInFiles_args() : table_name(), topk(0) {
}
virtual ~MilvusService_SearchVectorInFiles_args() throw();
std::string table_name;
std::vector<std::string> file_id_array;
std::vector<RowRecord> query_record_array;
std::vector<Range> query_range_array;
int64_t topk;
_MilvusService_SearchVectorInFiles_args__isset __isset;
void __set_table_name(const std::string& val);
void __set_file_id_array(const std::vector<std::string> & val);
void __set_query_record_array(const std::vector<RowRecord> & val);
void __set_query_range_array(const std::vector<Range> & val);
void __set_topk(const int64_t val);
bool operator == (const MilvusService_SearchVectorInFiles_args & rhs) const
{
if (!(table_name == rhs.table_name))
return false;
if (!(file_id_array == rhs.file_id_array))
return false;
if (!(query_record_array == rhs.query_record_array))
return false;
if (!(query_range_array == rhs.query_range_array))
return false;
if (!(topk == rhs.topk))
return false;
return true;
}
bool operator != (const MilvusService_SearchVectorInFiles_args &rhs) const {
return !(*this == rhs);
}
bool operator < (const MilvusService_SearchVectorInFiles_args & ) const;
uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};
class MilvusService_SearchVectorInFiles_pargs {
public:
virtual ~MilvusService_SearchVectorInFiles_pargs() throw();
const std::string* table_name;
const std::vector<std::string> * file_id_array;
const std::vector<RowRecord> * query_record_array;
const std::vector<Range> * query_range_array;
const int64_t* topk;
uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};
typedef struct _MilvusService_SearchVectorInFiles_result__isset {
_MilvusService_SearchVectorInFiles_result__isset() : success(false), e(false) {}
bool success :1;
bool e :1;
} _MilvusService_SearchVectorInFiles_result__isset;
class MilvusService_SearchVectorInFiles_result {
public:
MilvusService_SearchVectorInFiles_result(const MilvusService_SearchVectorInFiles_result&);
MilvusService_SearchVectorInFiles_result& operator=(const MilvusService_SearchVectorInFiles_result&);
MilvusService_SearchVectorInFiles_result() {
}
virtual ~MilvusService_SearchVectorInFiles_result() throw();
std::vector<TopKQueryResult> success;
Exception e;
_MilvusService_SearchVectorInFiles_result__isset __isset;
void __set_success(const std::vector<TopKQueryResult> & val);
void __set_e(const Exception& val);
bool operator == (const MilvusService_SearchVectorInFiles_result & rhs) const
{
if (!(success == rhs.success))
return false;
if (!(e == rhs.e))
return false;
return true;
}
bool operator != (const MilvusService_SearchVectorInFiles_result &rhs) const {
return !(*this == rhs);
}
bool operator < (const MilvusService_SearchVectorInFiles_result & ) const;
uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};
typedef struct _MilvusService_SearchVectorInFiles_presult__isset {
_MilvusService_SearchVectorInFiles_presult__isset() : success(false), e(false) {}
bool success :1;
bool e :1;
} _MilvusService_SearchVectorInFiles_presult__isset;
class MilvusService_SearchVectorInFiles_presult {
public:
virtual ~MilvusService_SearchVectorInFiles_presult() throw();
std::vector<TopKQueryResult> * success;
Exception e;
_MilvusService_SearchVectorInFiles_presult__isset __isset;
uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
};
typedef struct _MilvusService_DescribeTable_args__isset {
_MilvusService_DescribeTable_args__isset() : table_name(false) {}
bool table_name :1;
......@@ -1115,6 +1278,9 @@ class MilvusServiceClient : virtual public MilvusServiceIf {
void SearchVector(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void send_SearchVector(const std::string& table_name, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void recv_SearchVector(std::vector<TopKQueryResult> & _return);
void SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void send_SearchVectorInFiles(const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void recv_SearchVectorInFiles(std::vector<TopKQueryResult> & _return);
void DescribeTable(TableSchema& _return, const std::string& table_name);
void send_DescribeTable(const std::string& table_name);
void recv_DescribeTable(TableSchema& _return);
......@@ -1146,6 +1312,7 @@ class MilvusServiceProcessor : public ::apache::thrift::TDispatchProcessor {
void process_DeleteTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_AddVector(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_SearchVector(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_SearchVectorInFiles(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_DescribeTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_GetTableRowCount(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_ShowTables(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
......@@ -1157,6 +1324,7 @@ class MilvusServiceProcessor : public ::apache::thrift::TDispatchProcessor {
processMap_["DeleteTable"] = &MilvusServiceProcessor::process_DeleteTable;
processMap_["AddVector"] = &MilvusServiceProcessor::process_AddVector;
processMap_["SearchVector"] = &MilvusServiceProcessor::process_SearchVector;
processMap_["SearchVectorInFiles"] = &MilvusServiceProcessor::process_SearchVectorInFiles;
processMap_["DescribeTable"] = &MilvusServiceProcessor::process_DescribeTable;
processMap_["GetTableRowCount"] = &MilvusServiceProcessor::process_GetTableRowCount;
processMap_["ShowTables"] = &MilvusServiceProcessor::process_ShowTables;
......@@ -1227,6 +1395,16 @@ class MilvusServiceMultiface : virtual public MilvusServiceIf {
return;
}
void SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk) {
size_t sz = ifaces_.size();
size_t i = 0;
for (; i < (sz - 1); ++i) {
ifaces_[i]->SearchVectorInFiles(_return, table_name, file_id_array, query_record_array, query_range_array, topk);
}
ifaces_[i]->SearchVectorInFiles(_return, table_name, file_id_array, query_record_array, query_range_array, topk);
return;
}
void DescribeTable(TableSchema& _return, const std::string& table_name) {
size_t sz = ifaces_.size();
size_t i = 0;
......@@ -1308,6 +1486,9 @@ class MilvusServiceConcurrentClient : virtual public MilvusServiceIf {
void SearchVector(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
int32_t send_SearchVector(const std::string& table_name, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void recv_SearchVector(std::vector<TopKQueryResult> & _return, const int32_t seqid);
void SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
int32_t send_SearchVectorInFiles(const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk);
void recv_SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const int32_t seqid);
void DescribeTable(TableSchema& _return, const std::string& table_name);
int32_t send_DescribeTable(const std::string& table_name);
void recv_DescribeTable(TableSchema& _return, const int32_t seqid);
......
......@@ -90,6 +90,29 @@ class MilvusServiceHandler : virtual public MilvusServiceIf {
printf("SearchVector\n");
}
/**
* @brief Internal use query interface
*
* This method is used to query vector in specified files.
*
* @param file_id_array, specified files id array, queried.
* @param query_record_array, all vector are going to be queried.
* @param query_range_array, optional ranges for conditional search. If not specified, search whole table
* @param topk, how many similarity vectors will be searched.
*
* @return query result array.
*
* @param table_name
* @param file_id_array
* @param query_record_array
* @param query_range_array
* @param topk
*/
void SearchVectorInFiles(std::vector<TopKQueryResult> & _return, const std::string& table_name, const std::vector<std::string> & file_id_array, const std::vector<RowRecord> & query_record_array, const std::vector<Range> & query_range_array, const int64_t topk) {
// Your implementation goes here
printf("SearchVectorInFiles\n");
}
/**
* @brief Get table schema
*
......
......@@ -123,6 +123,23 @@ service MilvusService {
4: list<Range> query_range_array,
5: i64 topk) throws(1: Exception e);
/**
* @brief Internal use query interface
*
* This method is used to query vector in specified files.
*
* @param file_id_array, specified files id array, queried.
* @param query_record_array, all vector are going to be queried.
* @param query_range_array, optional ranges for conditional search. If not specified, search whole table
* @param topk, how many similarity vectors will be searched.
*
* @return query result array.
*/
list<TopKQueryResult> SearchVectorInFiles(2: string table_name,
3: list<string> file_id_array,
4: list<RowRecord> query_record_array,
5: list<Range> query_range_array,
6: i64 topk) throws(1: Exception e);
/**
* @brief Get table schema
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册