Merge remote-tracking branch 'main/master'

This commit is contained in:
JinHai-CN 2020-04-25 18:58:59 +08:00
commit 9db19a9a20
144 changed files with 7262 additions and 8616 deletions

View File

@ -47,6 +47,7 @@ jobs:
shell: bash
run: |
docker-compose build ubuntu-core
docker rmi $(docker images | grep '<none>' | awk '{print $3}') || exit 0
- name: Docker Run
run: |
docker-compose run --use-aliases -d db
@ -94,6 +95,7 @@ jobs:
shell: bash
run: |
docker-compose build centos-core
docker rmi $(docker images | grep '<none>' | awk '{print $3}') || exit 0
- name: Docker Run
run: |
docker-compose run --use-aliases -d db

View File

@ -7,9 +7,16 @@ Please mark all change in change log and use the issue from GitHub
## Bug
- \#1705 Limit the insert data batch size
- \#1929 Skip MySQL meta schema field width check
- \#2073 Fix CheckDBConfigBackendUrl error message
- \#2076 CheckMetricConfigAddress error message
## Feature
- \#1751 Add api SearchByID
- \#1752 Add api GetVectorsByID
- \#1962 Add api HasPartition
- \#1965 FAISS/NSG/HNSW/ANNOY use unified distance calculation algorithm
- \#2064 Warn when use SQLite as metadata management
## Improvement
- \#221 Refactor LOG macro

View File

@ -30,6 +30,7 @@ pipeline {
LOWER_BUILD_TYPE = params.BUILD_TYPE.toLowerCase()
SEMVER = "${BRANCH_NAME.contains('/') ? BRANCH_NAME.substring(BRANCH_NAME.lastIndexOf('/') + 1) : BRANCH_NAME}"
PIPELINE_NAME = "milvus-ci"
HELM_BRANCH = "master"
}
stages {

View File

@ -3,7 +3,7 @@ timeout(time: 180, unit: 'MINUTES') {
sh 'helm version'
sh 'helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts'
sh 'helm repo update'
checkout([$class: 'GitSCM', branches: [[name: "master"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/master:refs/remotes/origin/master"]]])
checkout([$class: 'GitSCM', branches: [[name: "${env.HELM_BRANCH}"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/${env.HELM_BRANCH}:refs/remotes/origin/${env.HELM_BRANCH}"]]])
retry(3) {
sh "helm install --wait --timeout 300s --set image.repository=registry.zilliz.com/milvus/engine --set image.tag=${DOCKER_VERSION} --set image.pullPolicy=Always --set service.type=ClusterIP -f ci/db_backend/mysql_${BINARY_VERSION}_values.yaml -f ci/filebeat/values.yaml --namespace milvus ${env.HELM_RELEASE_NAME} ."
}
@ -19,7 +19,7 @@ timeout(time: 180, unit: 'MINUTES') {
if (!fileExists('milvus-helm')) {
dir ("milvus-helm") {
checkout([$class: 'GitSCM', branches: [[name: "master"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/master:refs/remotes/origin/master"]]])
checkout([$class: 'GitSCM', branches: [[name:"${env.HELM_BRANCH}"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/${env.HELM_BRANCH}:refs/remotes/origin/${env.HELM_BRANCH}"]]])
}
}
dir ("milvus-helm") {

View File

@ -3,7 +3,7 @@ timeout(time: 120, unit: 'MINUTES') {
sh 'helm version'
sh 'helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts'
sh 'helm repo update'
checkout([$class: 'GitSCM', branches: [[name: "master"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/master:refs/remotes/origin/master"]]])
checkout([$class: 'GitSCM', branches: [[name: "${env.HELM_BRANCH}"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/${env.HELM_BRANCH}:refs/remotes/origin/${env.HELM_BRANCH}"]]])
retry(3) {
sh "helm install --wait --timeout 600s --set image.repository=registry.zilliz.com/milvus/engine --set image.tag=${DOCKER_VERSION} --set image.pullPolicy=Always --set service.type=ClusterIP -f ci/db_backend/mysql_${BINARY_VERSION}_values.yaml -f ci/filebeat/values.yaml --namespace milvus ${env.HELM_RELEASE_NAME} ."
}

View File

@ -54,7 +54,7 @@ aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler scheduler_main_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/action scheduler_action_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/event scheduler_event_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/job scheduler_job_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/optimizer scheduler_optimizer_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/selector scheduler_selector_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/resource scheduler_resource_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/task scheduler_task_files)
set(scheduler_files
@ -62,7 +62,7 @@ set(scheduler_files
${scheduler_action_files}
${scheduler_event_files}
${scheduler_job_files}
${scheduler_optimizer_files}
${scheduler_selector_files}
${scheduler_resource_files}
${scheduler_task_files}
)

View File

@ -32,76 +32,43 @@ namespace milvus {
namespace codec {
void
DefaultAttrsFormat::read_attrs_internal(const std::string& file_path, off_t offset, size_t num,
std::vector<uint8_t>& raw_attrs, size_t& nbytes) {
int ra_fd = open(file_path.c_str(), O_RDONLY, 00664);
if (ra_fd == -1) {
DefaultAttrsFormat::read_attrs_internal(const storage::FSHandlerPtr& fs_ptr, const std::string& file_path, off_t offset,
size_t num, std::vector<uint8_t>& raw_attrs, size_t& nbytes) {
if (!fs_ptr->reader_ptr_->open(file_path.c_str())) {
std::string err_msg = "Failed to open file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t num_bytes;
if (::read(ra_fd, &num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->read(&nbytes, sizeof(size_t));
num = std::min(num, num_bytes - offset);
num = std::min(num, nbytes - offset);
offset += sizeof(size_t);
int off = lseek(ra_fd, offset, SEEK_SET);
if (off == -1) {
std::string err_msg = "Failed to seek file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->seekg(offset);
raw_attrs.resize(num / sizeof(uint8_t));
if (::read(ra_fd, raw_attrs.data(), num) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->read(raw_attrs.data(), num);
nbytes = num;
if (::close(ra_fd) == -1) {
std::string err_msg = "Failed to close file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->close();
}
void
DefaultAttrsFormat::read_uids_internal(const std::string& file_path, std::vector<int64_t>& uids) {
int uid_fd = open(file_path.c_str(), O_RDONLY, 00664);
if (uid_fd == -1) {
DefaultAttrsFormat::read_uids_internal(const storage::FSHandlerPtr& fs_ptr, const std::string& file_path,
std::vector<int64_t>& uids) {
if (!fs_ptr->reader_ptr_->open(file_path.c_str())) {
std::string err_msg = "Failed to open file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t num_bytes;
if (::read(uid_fd, &num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->read(&num_bytes, sizeof(size_t));
uids.resize(num_bytes / sizeof(int64_t));
if (::read(uid_fd, uids.data(), num_bytes) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->read(uids.data(), num_bytes);
if (::close(uid_fd) == -1) {
std::string err_msg = "Failed to close file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
fs_ptr->reader_ptr_->read(uids.data(), num_bytes);
}
void
@ -123,7 +90,7 @@ DefaultAttrsFormat::read(const milvus::storage::FSHandlerPtr& fs_ptr, milvus::se
for (; uid_it != it_end; ++uid_it) {
const auto& path = uid_it->path();
if (path.extension().string() == user_id_extension_) {
read_uids_internal(path.string(), uids);
read_uids_internal(fs_ptr, path.string(), uids);
break;
}
}
@ -134,10 +101,9 @@ DefaultAttrsFormat::read(const milvus::storage::FSHandlerPtr& fs_ptr, milvus::se
if (path.extension().string() == raw_attr_extension_) {
auto file_name = path.filename().string();
auto field_name = file_name.substr(0, file_name.size() - 3);
// void* attr_list;
std::vector<uint8_t> attr_list;
size_t nbytes;
read_attrs_internal(path.string(), 0, INT64_MAX, attr_list, nbytes);
read_attrs_internal(fs_ptr, path.string(), 0, INT64_MAX, attr_list, nbytes);
milvus::segment::AttrPtr attr =
std::make_shared<milvus::segment::Attr>(attr_list, nbytes, uids, field_name);
attrs_read->attrs.insert(std::pair(field_name, attr));
@ -238,7 +204,7 @@ DefaultAttrsFormat::read_uids(const milvus::storage::FSHandlerPtr& fs_ptr, std::
for (; it != it_end; ++it) {
const auto& path = it->path();
if (path.extension().string() == user_id_extension_) {
read_uids_internal(path.string(), uids);
read_uids_internal(fs_ptr, path.string(), uids);
}
}
}

View File

@ -51,10 +51,11 @@ class DefaultAttrsFormat : public AttrsFormat {
private:
void
read_attrs_internal(const std::string&, off_t, size_t, std::vector<uint8_t>&, size_t&);
read_attrs_internal(const storage::FSHandlerPtr& fs_ptr, const std::string&, off_t, size_t, std::vector<uint8_t>&,
size_t&);
void
read_uids_internal(const std::string&, std::vector<int64_t>&);
read_uids_internal(const storage::FSHandlerPtr& fs_ptr, const std::string&, std::vector<int64_t>&);
private:
std::mutex mutex_;

View File

@ -891,7 +891,7 @@ Config::CheckDBConfigBackendUrl(const std::string& value) {
std::string msg =
"Invalid backend url: " + value + ". Possible reason: db_config.db_backend_url is invalid. " +
"The correct format should be like sqlite://:@:/ or mysql://root:123456@127.0.0.1:3306/milvus.";
return Status(SERVER_INVALID_ARGUMENT, "invalid db_backend_url: " + value);
return Status(SERVER_INVALID_ARGUMENT, msg);
}
return Status::OK();
}
@ -1093,7 +1093,7 @@ Status
Config::CheckMetricConfigAddress(const std::string& value) {
if (!ValidationUtil::ValidateIpAddress(value).ok()) {
std::string msg = "Invalid metric ip: " + value + ". Possible reason: metric_config.ip is invalid.";
return Status(SERVER_INVALID_ARGUMENT, "Invalid metric config ip: " + value);
return Status(SERVER_INVALID_ARGUMENT, msg);
}
return Status::OK();
}

View File

@ -65,7 +65,7 @@ class DB {
AllCollections(std::vector<meta::CollectionSchema>& table_schema_array) = 0;
virtual Status
GetCollectionInfo(const std::string& collection_id, CollectionInfo& collection_info) = 0;
GetCollectionInfo(const std::string& collection_id, std::string& collection_info) = 0;
virtual Status
GetCollectionRowCount(const std::string& collection_id, uint64_t& row_count) = 0;
@ -108,7 +108,8 @@ class DB {
Compact(const std::string& collection_id) = 0;
virtual Status
GetVectorByID(const std::string& collection_id, const IDNumber& vector_id, VectorsData& vector) = 0;
GetVectorsByID(const std::string& collection_id, const IDNumbers& id_array,
std::vector<engine::VectorsData>& vectors) = 0;
virtual Status
GetVectorIDs(const std::string& collection_id, const std::string& segment_id, IDNumbers& vector_ids) = 0;
@ -117,9 +118,9 @@ class DB {
// Merge(const std::set<std::string>& table_ids) = 0;
virtual Status
QueryByID(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
IDNumber vector_id, ResultIds& result_ids, ResultDistances& result_distances) = 0;
QueryByIDs(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
const IDNumbers& id_array, ResultIds& result_ids, ResultDistances& result_distances) = 0;
virtual Status
Query(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
@ -153,7 +154,8 @@ class DB {
DescribeHybridCollection(meta::CollectionSchema& collection_schema, meta::hybrid::FieldsSchema& fields_schema) = 0;
virtual Status
InsertEntities(const std::string& collection_id, const std::string& partition_tag, Entity& entity,
InsertEntities(const std::string& collection_id, const std::string& partition_tag,
const std::vector<std::string>& field_names, Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& field_types) = 0;
virtual Status

View File

@ -33,7 +33,7 @@
#include "db/IDGenerator.h"
#include "engine/EngineFactory.h"
#include "index/thirdparty/faiss/utils/distances.h"
#include "insert/MemMenagerFactory.h"
#include "insert/MemManagerFactory.h"
#include "meta/MetaConsts.h"
#include "meta/MetaFactory.h"
#include "meta/SqliteMetaImpl.h"
@ -62,6 +62,14 @@ constexpr uint64_t BACKGROUND_METRIC_INTERVAL = 1;
constexpr uint64_t BACKGROUND_INDEX_INTERVAL = 1;
constexpr uint64_t WAIT_BUILD_INDEX_INTERVAL = 5;
constexpr const char* JSON_ROW_COUNT = "row_count";
constexpr const char* JSON_PARTITIONS = "partitions";
constexpr const char* JSON_PARTITION_TAG = "tag";
constexpr const char* JSON_SEGMENTS = "segments";
constexpr const char* JSON_SEGMENT_NAME = "name";
constexpr const char* JSON_INDEX_NAME = "index_name";
constexpr const char* JSON_DATA_SIZE = "data_size";
static const Status SHUTDOWN_ERROR = Status(DB_ERROR, "Milvus server is shutdown!");
} // namespace
@ -314,67 +322,75 @@ DBImpl::AllCollections(std::vector<meta::CollectionSchema>& collection_schema_ar
}
Status
DBImpl::GetCollectionInfo(const std::string& collection_id, CollectionInfo& collection_info) {
DBImpl::GetCollectionInfo(const std::string& collection_id, std::string& collection_info) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
// step1: get all partition ids
std::vector<std::pair<std::string, std::string>> name2tag = {{collection_id, milvus::engine::DEFAULT_PARTITON_TAG}};
std::vector<meta::CollectionSchema> partition_array;
auto status = meta_ptr_->ShowPartitions(collection_id, partition_array);
for (auto& schema : partition_array) {
name2tag.push_back(std::make_pair(schema.collection_id_, schema.partition_tag_));
}
// step2: get native collection info
std::vector<int> file_types{meta::SegmentSchema::FILE_TYPE::RAW, meta::SegmentSchema::FILE_TYPE::TO_INDEX,
meta::SegmentSchema::FILE_TYPE::INDEX};
static std::map<int32_t, std::string> index_type_name = {
{(int32_t)engine::EngineType::FAISS_IDMAP, "IDMAP"},
{(int32_t)engine::EngineType::FAISS_IVFFLAT, "IVFFLAT"},
{(int32_t)engine::EngineType::FAISS_IVFSQ8, "IVFSQ8"},
{(int32_t)engine::EngineType::NSG_MIX, "NSG"},
{(int32_t)engine::EngineType::ANNOY, "ANNOY"},
{(int32_t)engine::EngineType::FAISS_IVFSQ8H, "IVFSQ8H"},
{(int32_t)engine::EngineType::FAISS_PQ, "PQ"},
{(int32_t)engine::EngineType::SPTAG_KDT, "KDT"},
{(int32_t)engine::EngineType::SPTAG_BKT, "BKT"},
{(int32_t)engine::EngineType::FAISS_BIN_IDMAP, "IDMAP"},
{(int32_t)engine::EngineType::FAISS_BIN_IVFFLAT, "IVFFLAT"},
};
milvus::json json_info;
milvus::json json_partitions;
size_t total_row_count = 0;
for (auto& name_tag : name2tag) {
auto get_info = [&](const std::string& col_id, const std::string& tag) {
meta::SegmentsSchema collection_files;
status = meta_ptr_->FilesByType(name_tag.first, file_types, collection_files);
status = meta_ptr_->FilesByType(col_id, file_types, collection_files);
if (!status.ok()) {
std::string err_msg = "Failed to get collection info: " + status.ToString();
LOG_ENGINE_ERROR_ << err_msg;
return Status(DB_ERROR, err_msg);
}
std::vector<SegmentStat> segments_stat;
milvus::json json_partition;
json_partition[JSON_PARTITION_TAG] = tag;
milvus::json json_segments;
size_t row_count = 0;
for (auto& file : collection_files) {
SegmentStat seg_stat;
seg_stat.name_ = file.segment_id_;
seg_stat.row_count_ = (int64_t)file.row_count_;
seg_stat.index_name_ = index_type_name[file.engine_type_];
seg_stat.data_size_ = (int64_t)file.file_size_;
segments_stat.emplace_back(seg_stat);
milvus::json json_segment;
json_segment[JSON_SEGMENT_NAME] = file.segment_id_;
json_segment[JSON_ROW_COUNT] = file.row_count_;
json_segment[JSON_INDEX_NAME] = utils::GetIndexName(file.engine_type_);
json_segment[JSON_DATA_SIZE] = (int64_t)file.file_size_;
json_segments.push_back(json_segment);
row_count += file.row_count_;
total_row_count += file.row_count_;
}
PartitionStat partition_stat;
if (name_tag.first == collection_id) {
partition_stat.tag_ = milvus::engine::DEFAULT_PARTITON_TAG;
} else {
partition_stat.tag_ = name_tag.second;
}
json_partition[JSON_ROW_COUNT] = row_count;
json_partition[JSON_SEGMENTS] = json_segments;
partition_stat.segments_stat_.swap(segments_stat);
collection_info.partitions_stat_.emplace_back(partition_stat);
json_partitions.push_back(json_partition);
return Status::OK();
};
// step2: get default partition info
status = get_info(collection_id, milvus::engine::DEFAULT_PARTITON_TAG);
if (!status.ok()) {
return status;
}
// step3: get partitions info
for (auto& schema : partition_array) {
status = get_info(schema.collection_id_, schema.partition_tag_);
if (!status.ok()) {
return status;
}
}
json_info[JSON_ROW_COUNT] = total_row_count;
json_info[JSON_PARTITIONS] = json_partitions;
collection_info = json_info.dump();
return Status::OK();
}
@ -586,7 +602,8 @@ DBImpl::InsertVectors(const std::string& collection_id, const std::string& parti
}
Status
DBImpl::InsertEntities(const std::string& collection_id, const std::string& partition_tag, Entity& entity,
DBImpl::InsertEntities(const std::string& collection_id, const std::string& partition_tag,
const std::vector<std::string>& field_names, Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& attr_types) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
@ -621,106 +638,113 @@ DBImpl::InsertEntities(const std::string& collection_id, const std::string& part
// record.length = entities.vector_data_[0].binary_data_.size() * sizeof(uint8_t);
}
auto attr_data_it = entity.attr_data_.begin();
for (; attr_data_it != entity.attr_data_.end(); ++attr_data_it) {
switch (attr_types.at(attr_data_it->first)) {
uint64_t offset = 0;
for (auto field_name : field_names) {
switch (attr_types.at(field_name)) {
case meta::hybrid::DataType::INT8: {
std::vector<int8_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int8_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int8_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int8_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int8_t)));
std::vector<int64_t> attr_value(entity.entity_count_, 0);
memcpy(attr_value.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(int64_t));
offset += entity.entity_count_ * sizeof(int64_t);
std::vector<int8_t> raw_value(entity.entity_count_, 0);
for (uint64_t i = 0; i < entity.entity_count_; ++i) {
raw_value[i] = attr_value[i];
}
memcpy(data.data(), raw_value.data(), entity.entity_count_ * sizeof(int8_t));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(int8_t)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(int8_t)));
break;
}
case meta::hybrid::DataType::INT16: {
std::vector<int16_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int16_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int16_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int16_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int16_t)));
std::vector<int64_t> attr_value(entity.entity_count_, 0);
memcpy(attr_value.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(int64_t));
offset += entity.entity_count_ * sizeof(int64_t);
std::vector<int16_t> raw_value(entity.entity_count_, 0);
for (uint64_t i = 0; i < entity.entity_count_; ++i) {
raw_value[i] = attr_value[i];
}
memcpy(data.data(), raw_value.data(), entity.entity_count_ * sizeof(int16_t));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(int16_t)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(int16_t)));
break;
}
case meta::hybrid::DataType::INT32: {
std::vector<int32_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int32_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int32_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int32_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int32_t)));
std::vector<int64_t> attr_value(entity.entity_count_, 0);
memcpy(attr_value.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(int64_t));
offset += entity.entity_count_ * sizeof(int64_t);
std::vector<int32_t> raw_value(entity.entity_count_, 0);
for (uint64_t i = 0; i < entity.entity_count_; ++i) {
raw_value[i] = attr_value[i];
}
memcpy(data.data(), raw_value.data(), entity.entity_count_ * sizeof(int32_t));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(int32_t)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(int32_t)));
break;
}
case meta::hybrid::DataType::INT64: {
std::vector<int64_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int64_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int64_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int64_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int64_t)));
memcpy(data.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(int64_t));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(int64_t)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(int64_t)));
offset += entity.entity_count_ * sizeof(int64_t);
break;
}
case meta::hybrid::DataType::FLOAT: {
std::vector<float> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atof(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(float));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(float));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(float)));
record.attr_data_size.insert(std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(float)));
std::vector<double> attr_value(entity.entity_count_, 0);
memcpy(attr_value.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(double));
offset += entity.entity_count_ * sizeof(double);
std::vector<float> raw_value(entity.entity_count_, 0);
for (uint64_t i = 0; i < entity.entity_count_; ++i) {
raw_value[i] = attr_value[i];
}
memcpy(data.data(), raw_value.data(), entity.entity_count_ * sizeof(float));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(float)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(float)));
break;
}
case meta::hybrid::DataType::DOUBLE: {
std::vector<double> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atof(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(double));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(double));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
memcpy(data.data(), entity.attr_value_.data() + offset, entity.entity_count_ * sizeof(double));
record.attr_data.insert(std::make_pair(field_name, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(double)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(double)));
record.attr_nbytes.insert(std::make_pair(field_name, sizeof(double)));
record.attr_data_size.insert(std::make_pair(field_name, entity.entity_count_ * sizeof(double)));
offset += entity.entity_count_ * sizeof(double);
break;
}
default:
break;
}
}
@ -1006,7 +1030,8 @@ DBImpl::CompactFile(const std::string& collection_id, const meta::SegmentSchema&
}
Status
DBImpl::GetVectorByID(const std::string& collection_id, const IDNumber& vector_id, VectorsData& vector) {
DBImpl::GetVectorsByID(const std::string& collection_id, const IDNumbers& id_array,
std::vector<engine::VectorsData>& vectors) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
@ -1022,13 +1047,12 @@ DBImpl::GetVectorByID(const std::string& collection_id, const IDNumber& vector_i
}
meta::SegmentsSchema files_to_query;
std::vector<int> file_types{meta::SegmentSchema::FILE_TYPE::RAW, meta::SegmentSchema::FILE_TYPE::TO_INDEX,
meta::SegmentSchema::FILE_TYPE::BACKUP};
meta::SegmentsSchema collection_files;
status = meta_ptr_->FilesByType(collection_id, file_types, files_to_query);
if (!status.ok()) {
std::string err_msg = "Failed to get files for GetVectorByID: " + status.message();
std::string err_msg = "Failed to get files for GetVectorsByID: " + status.message();
LOG_ENGINE_ERROR_ << err_msg;
return status;
}
@ -1041,6 +1065,7 @@ DBImpl::GetVectorByID(const std::string& collection_id, const IDNumber& vector_i
meta::SegmentsSchema files;
status = meta_ptr_->FilesByType(schema.collection_id_, file_types, files);
if (!status.ok()) {
OngoingFileChecker::GetInstance().UnmarkOngoingFiles(files_to_query);
std::string err_msg = "Failed to get files for GetVectorByID: " + status.message();
LOG_ENGINE_ERROR_ << err_msg;
return status;
@ -1052,13 +1077,14 @@ DBImpl::GetVectorByID(const std::string& collection_id, const IDNumber& vector_i
}
if (files_to_query.empty()) {
OngoingFileChecker::GetInstance().UnmarkOngoingFiles(files_to_query);
LOG_ENGINE_DEBUG_ << "No files to get vector by id from";
return Status(DB_NOT_FOUND, "Collection is empty");
}
cache::CpuCacheMgr::GetInstance()->PrintInfo();
status = GetVectorByIdHelper(collection_id, vector_id, vector, files_to_query);
status = GetVectorsByIdHelper(collection_id, id_array, vectors, files_to_query);
OngoingFileChecker::GetInstance().UnmarkOngoingFiles(files_to_query);
cache::CpuCacheMgr::GetInstance()->PrintInfo();
@ -1138,14 +1164,21 @@ DBImpl::GetVectorIDs(const std::string& collection_id, const std::string& segmen
}
Status
DBImpl::GetVectorByIdHelper(const std::string& collection_id, IDNumber vector_id, VectorsData& vector,
const meta::SegmentsSchema& files) {
LOG_ENGINE_DEBUG_ << "Getting vector by id in " << files.size() << " files, id = " << vector_id;
DBImpl::GetVectorsByIdHelper(const std::string& collection_id, const IDNumbers& id_array,
std::vector<engine::VectorsData>& vectors, const meta::SegmentsSchema& files) {
LOG_ENGINE_DEBUG_ << "Getting vector by id in " << files.size() << " files, id count = " << id_array.size();
vector.vector_count_ = 0;
vector.float_data_.clear();
vector.binary_data_.clear();
// sometimes not all of id_array can be found, we need to return empty vector for id not found
// for example:
// id_array = [1, -1, 2, -1, 3]
// vectors should return [valid_vector, empty_vector, valid_vector, empty_vector, valid_vector]
// the ID2RAW is to ensure returned vector sequence is consist with id_array
using ID2VECTOR = std::map<int64_t, VectorsData>;
ID2VECTOR map_id2vector;
vectors.clear();
IDNumbers temp_ids = id_array;
for (auto& file : files) {
// Load bloom filter
std::string segment_dir;
@ -1154,60 +1187,80 @@ DBImpl::GetVectorByIdHelper(const std::string& collection_id, IDNumber vector_id
segment::IdBloomFilterPtr id_bloom_filter_ptr;
segment_reader.LoadBloomFilter(id_bloom_filter_ptr);
// Check if the id is present in bloom filter.
if (id_bloom_filter_ptr->Check(vector_id)) {
// Load uids and check if the id is indeed present. If yes, find its offset.
std::vector<int64_t> offsets;
std::vector<segment::doc_id_t> uids;
auto status = segment_reader.LoadUids(uids);
if (!status.ok()) {
return status;
}
for (IDNumbers::iterator it = temp_ids.begin(); it != temp_ids.end();) {
int64_t vector_id = *it;
// each id must has a VectorsData
// if vector not found for an id, its VectorsData's vector_count = 0, else 1
VectorsData& vector_ref = map_id2vector[vector_id];
auto found = std::find(uids.begin(), uids.end(), vector_id);
if (found != uids.end()) {
auto offset = std::distance(uids.begin(), found);
// Check whether the id has been deleted
segment::DeletedDocsPtr deleted_docs_ptr;
status = segment_reader.LoadDeletedDocs(deleted_docs_ptr);
// Check if the id is present in bloom filter.
if (id_bloom_filter_ptr->Check(vector_id)) {
// Load uids and check if the id is indeed present. If yes, find its offset.
std::vector<segment::doc_id_t> uids;
auto status = segment_reader.LoadUids(uids);
if (!status.ok()) {
LOG_ENGINE_ERROR_ << status.message();
return status;
}
auto& deleted_docs = deleted_docs_ptr->GetDeletedDocs();
auto deleted = std::find(deleted_docs.begin(), deleted_docs.end(), offset);
if (deleted == deleted_docs.end()) {
// Load raw vector
bool is_binary = utils::IsBinaryMetricType(file.metric_type_);
size_t single_vector_bytes = is_binary ? file.dimension_ / 8 : file.dimension_ * sizeof(float);
std::vector<uint8_t> raw_vector;
status = segment_reader.LoadVectors(offset * single_vector_bytes, single_vector_bytes, raw_vector);
auto found = std::find(uids.begin(), uids.end(), vector_id);
if (found != uids.end()) {
auto offset = std::distance(uids.begin(), found);
// Check whether the id has been deleted
segment::DeletedDocsPtr deleted_docs_ptr;
status = segment_reader.LoadDeletedDocs(deleted_docs_ptr);
if (!status.ok()) {
LOG_ENGINE_ERROR_ << status.message();
return status;
}
auto& deleted_docs = deleted_docs_ptr->GetDeletedDocs();
vector.vector_count_ = 1;
if (is_binary) {
vector.binary_data_ = std::move(raw_vector);
} else {
std::vector<float> float_vector;
float_vector.resize(file.dimension_);
memcpy(float_vector.data(), raw_vector.data(), single_vector_bytes);
vector.float_data_ = std::move(float_vector);
auto deleted = std::find(deleted_docs.begin(), deleted_docs.end(), offset);
if (deleted == deleted_docs.end()) {
// Load raw vector
bool is_binary = utils::IsBinaryMetricType(file.metric_type_);
size_t single_vector_bytes = is_binary ? file.dimension_ / 8 : file.dimension_ * sizeof(float);
std::vector<uint8_t> raw_vector;
status =
segment_reader.LoadVectors(offset * single_vector_bytes, single_vector_bytes, raw_vector);
if (!status.ok()) {
LOG_ENGINE_ERROR_ << status.message();
return status;
}
vector_ref.vector_count_ = 1;
if (is_binary) {
vector_ref.binary_data_.swap(raw_vector);
} else {
std::vector<float> float_vector;
float_vector.resize(file.dimension_);
memcpy(float_vector.data(), raw_vector.data(), single_vector_bytes);
vector_ref.float_data_.swap(float_vector);
}
temp_ids.erase(it);
continue;
}
return Status::OK();
}
}
} else {
continue;
it++;
}
}
if (vector.binary_data_.empty() && vector.float_data_.empty()) {
std::string msg = "Vector with id " + std::to_string(vector_id) + " not found in collection " + collection_id;
for (auto id : id_array) {
VectorsData& vector_ref = map_id2vector[id];
VectorsData data;
data.vector_count_ = vector_ref.vector_count_;
if (data.vector_count_ > 0) {
data.float_data_.swap(vector_ref.float_data_);
data.binary_data_.swap(vector_ref.binary_data_);
}
vectors.emplace_back(data);
}
if (vectors.empty()) {
std::string msg = "Vectors not found in collection " + collection_id;
LOG_ENGINE_DEBUG_ << msg;
}
@ -1278,19 +1331,130 @@ DBImpl::DropIndex(const std::string& collection_id) {
}
Status
DBImpl::QueryByID(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
IDNumber vector_id, ResultIds& result_ids, ResultDistances& result_distances) {
DBImpl::QueryByIDs(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
const IDNumbers& id_array, ResultIds& result_ids, ResultDistances& result_distances) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
VectorsData vectors_data = VectorsData();
vectors_data.id_array_.emplace_back(vector_id);
vectors_data.vector_count_ = 1;
Status result =
Query(context, collection_id, partition_tags, k, extra_params, vectors_data, result_ids, result_distances);
return result;
if (id_array.empty()) {
return Status(DB_ERROR, "Empty id array during query by id");
}
TimeRecorder rc("Query by id in collection:" + collection_id);
// get collection schema
engine::meta::CollectionSchema collection_schema;
collection_schema.collection_id_ = collection_id;
auto status = DescribeCollection(collection_schema);
if (!status.ok()) {
if (status.code() == DB_NOT_FOUND) {
std::string msg = "Collection to search does not exist: " + collection_id;
LOG_ENGINE_ERROR_ << msg;
return Status(DB_NOT_FOUND, msg);
} else {
return status;
}
} else {
if (!collection_schema.owner_collection_.empty()) {
std::string msg = "Collection to search does not exist: " + collection_id;
LOG_ENGINE_ERROR_ << msg;
return Status(DB_NOT_FOUND, msg);
}
}
rc.RecordSection("get collection schema");
// get target vectors data
std::vector<milvus::engine::VectorsData> vectors;
status = GetVectorsByID(collection_id, id_array, vectors);
if (!status.ok()) {
std::string msg = "Failed to get vector data for collection: " + collection_id;
LOG_ENGINE_ERROR_ << msg;
return status;
}
// some vectors could not be found, no need to search them
uint64_t valid_count = 0;
bool is_binary = utils::IsBinaryMetricType(collection_schema.metric_type_);
for (auto& vector : vectors) {
if (vector.vector_count_ > 0) {
valid_count++;
}
}
// copy valid vectors data for search input
uint64_t dimension = collection_schema.dimension_;
VectorsData valid_vectors;
valid_vectors.vector_count_ = valid_count;
if (is_binary) {
valid_vectors.binary_data_.resize(valid_count * dimension / 8);
} else {
valid_vectors.float_data_.resize(valid_count * dimension * sizeof(float));
}
int64_t valid_index = 0;
for (size_t i = 0; i < vectors.size(); i++) {
if (vectors[i].vector_count_ == 0) {
continue;
}
if (is_binary) {
memcpy(valid_vectors.binary_data_.data() + valid_index * dimension / 8, vectors[i].binary_data_.data(),
vectors[i].binary_data_.size());
} else {
memcpy(valid_vectors.float_data_.data() + valid_index * dimension, vectors[i].float_data_.data(),
vectors[i].float_data_.size() * sizeof(float));
}
valid_index++;
}
rc.RecordSection("construct query input");
// search valid vectors
ResultIds valid_result_ids;
ResultDistances valid_result_distances;
status = Query(context, collection_id, partition_tags, k, extra_params, valid_vectors, valid_result_ids,
valid_result_distances);
if (!status.ok()) {
std::string msg = "Failed to query by id in collection " + collection_id + ", error: " + status.message();
LOG_ENGINE_ERROR_ << msg;
return status;
}
if (valid_result_ids.size() != valid_count * k || valid_result_distances.size() != valid_count * k) {
std::string msg = "Failed to query by id in collection " + collection_id + ", result doesn't match id count";
return Status(DB_ERROR, msg);
}
rc.RecordSection("query vealid vectors");
// construct result
if (valid_count == id_array.size()) {
result_ids.swap(valid_result_ids);
result_distances.swap(valid_result_distances);
} else {
result_ids.resize(vectors.size() * k);
result_distances.resize(vectors.size() * k);
int64_t valid_index = 0;
for (uint64_t i = 0; i < vectors.size(); i++) {
if (vectors[i].vector_count_ > 0) {
memcpy(result_ids.data() + i * k, valid_result_ids.data() + valid_index * k, k * sizeof(int64_t));
memcpy(result_distances.data() + i * k, valid_result_distances.data() + valid_index * k,
k * sizeof(float));
valid_index++;
} else {
memset(result_ids.data() + i * k, -1, k * sizeof(int64_t));
for (uint64_t j = i * k; j < i * k + k; j++) {
result_distances[j] = std::numeric_limits<float>::max();
}
}
}
}
rc.RecordSection("construct result");
return status;
}
Status
@ -1306,7 +1470,6 @@ DBImpl::HybridQuery(const std::shared_ptr<server::Context>& context, const std::
}
Status status;
std::vector<size_t> ids;
meta::SegmentsSchema files_array;
if (partition_tags.empty()) {
@ -2278,15 +2441,16 @@ DBImpl::ExecWalRecord(const wal::MXLogRecord& record) {
std::string target_collection_name;
status = GetPartitionByTag(record.collection_id, record.partition_tag, target_collection_name);
if (!status.ok()) {
LOG_WAL_ERROR_ << LogOut("[%s][%ld] ", "insert", 0) << "Get partition fail: " << status.message();
return status;
}
std::set<std::string> flushed_tables;
std::set<std::string> flushed_collections;
status = mem_mgr_->InsertEntities(target_collection_name, record.length, record.ids,
(record.data_size / record.length / sizeof(float)),
(const float*)record.data, record.attr_nbytes, record.attr_data_size,
record.attr_data, record.lsn, flushed_tables);
collections_flushed(flushed_tables);
record.attr_data, record.lsn, flushed_collections);
collections_flushed(flushed_collections);
milvus::server::CollectInsertMetrics metrics(record.length, status);
break;

View File

@ -74,7 +74,7 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
AllCollections(std::vector<meta::CollectionSchema>& collection_schema_array) override;
Status
GetCollectionInfo(const std::string& collection_id, CollectionInfo& collection_info) override;
GetCollectionInfo(const std::string& collection_id, std::string& collection_info) override;
Status
PreloadCollection(const std::string& collection_id) override;
@ -118,7 +118,8 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
Compact(const std::string& collection_id) override;
Status
GetVectorByID(const std::string& collection_id, const IDNumber& vector_id, VectorsData& vector) override;
GetVectorsByID(const std::string& collection_id, const IDNumbers& id_array,
std::vector<engine::VectorsData>& vectors) override;
Status
GetVectorIDs(const std::string& collection_id, const std::string& segment_id, IDNumbers& vector_ids) override;
@ -144,7 +145,8 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
meta::hybrid::FieldsSchema& fields_schema) override;
Status
InsertEntities(const std::string& collection_name, const std::string& partition_tag, engine::Entity& entity,
InsertEntities(const std::string& collection_name, const std::string& partition_tag,
const std::vector<std::string>& field_names, engine::Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& field_types) override;
Status
@ -155,9 +157,9 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
ResultIds& result_ids, ResultDistances& result_distances) override;
Status
QueryByID(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
IDNumber vector_id, ResultIds& result_ids, ResultDistances& result_distances) override;
QueryByIDs(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
const IDNumbers& id_array, ResultIds& result_ids, ResultDistances& result_distances) override;
Status
Query(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
@ -193,8 +195,8 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
ResultIds& result_ids, ResultDistances& result_distances);
Status
GetVectorByIdHelper(const std::string& collection_id, IDNumber vector_id, VectorsData& vector,
const meta::SegmentsSchema& files);
GetVectorsByIdHelper(const std::string& collection_id, const IDNumbers& id_array,
std::vector<engine::VectorsData>& vectors, const meta::SegmentsSchema& files);
void
InternalFlush(const std::string& collection_id = "");

View File

@ -50,6 +50,7 @@ struct VectorsData {
struct Entity {
uint64_t entity_count_ = 0;
std::vector<uint8_t> attr_value_;
std::unordered_map<std::string, std::vector<std::string>> attr_data_;
std::unordered_map<std::string, VectorsData> vector_data_;
IDNumbers id_array_;
@ -60,22 +61,6 @@ using Table2FileErr = std::map<std::string, File2ErrArray>;
using File2RefCount = std::map<std::string, int64_t>;
using Table2FileRef = std::map<std::string, File2RefCount>;
struct SegmentStat {
std::string name_;
int64_t row_count_ = 0;
std::string index_name_;
int64_t data_size_ = 0;
};
struct PartitionStat {
std::string tag_;
std::vector<SegmentStat> segments_stat_;
};
struct CollectionInfo {
std::vector<PartitionStat> partitions_stat_;
};
static const char* DEFAULT_PARTITON_TAG = "_default";
} // namespace engine

View File

@ -24,6 +24,8 @@
#include "utils/CommonUtil.h"
#include "utils/Log.h"
#include <map>
namespace milvus {
namespace engine {
namespace utils {
@ -221,12 +223,6 @@ IsRawIndexType(int32_t type) {
return (type == (int32_t)EngineType::FAISS_IDMAP) || (type == (int32_t)EngineType::FAISS_BIN_IDMAP);
}
bool
IsBinaryIndexType(int32_t index_type) {
return (index_type == (int32_t)engine::EngineType::FAISS_BIN_IDMAP) ||
(index_type == (int32_t)engine::EngineType::FAISS_BIN_IVFFLAT);
}
bool
IsBinaryMetricType(int32_t metric_type) {
return (metric_type == (int32_t)engine::MetricType::HAMMING) ||
@ -299,6 +295,29 @@ ParseMetaUri(const std::string& uri, MetaUriInfo& info) {
return Status::OK();
}
std::string
GetIndexName(int32_t index_type) {
static std::map<int32_t, std::string> index_type_name = {
{(int32_t)engine::EngineType::FAISS_IDMAP, "IDMAP"},
{(int32_t)engine::EngineType::FAISS_IVFFLAT, "IVFFLAT"},
{(int32_t)engine::EngineType::FAISS_IVFSQ8, "IVFSQ8"},
{(int32_t)engine::EngineType::NSG_MIX, "NSG"},
{(int32_t)engine::EngineType::ANNOY, "ANNOY"},
{(int32_t)engine::EngineType::FAISS_IVFSQ8H, "IVFSQ8H"},
{(int32_t)engine::EngineType::FAISS_PQ, "PQ"},
{(int32_t)engine::EngineType::SPTAG_KDT, "KDT"},
{(int32_t)engine::EngineType::SPTAG_BKT, "BKT"},
{(int32_t)engine::EngineType::FAISS_BIN_IDMAP, "IDMAP"},
{(int32_t)engine::EngineType::FAISS_BIN_IVFFLAT, "IVFFLAT"},
};
if (index_type_name.find(index_type) == index_type_name.end()) {
return "Unknow";
}
return index_type_name[index_type];
}
} // namespace utils
} // namespace engine
} // namespace milvus

View File

@ -48,9 +48,6 @@ IsSameIndex(const CollectionIndex& index1, const CollectionIndex& index2);
bool
IsRawIndexType(int32_t type);
static bool
IsBinaryIndexType(int32_t index_type);
bool
IsBinaryMetricType(int32_t metric_type);
@ -73,6 +70,9 @@ struct MetaUriInfo {
Status
ParseMetaUri(const std::string& uri, MetaUriInfo& info);
std::string
GetIndexName(int32_t index_type);
} // namespace utils
} // namespace engine
} // namespace milvus

View File

@ -128,10 +128,6 @@ class ExecutionEngine {
Search(int64_t n, const uint8_t* data, int64_t k, const milvus::json& extra_params, float* distances,
int64_t* labels, bool hybrid) = 0;
virtual Status
Search(int64_t n, const std::vector<int64_t>& ids, int64_t k, const milvus::json& extra_params, float* distances,
int64_t* labels, bool hybrid) = 0;
virtual std::shared_ptr<ExecutionEngine>
BuildIndex(const std::string& location, EngineType engine_type) = 0;

View File

@ -810,10 +810,17 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<int8_t> data;
data.resize(size / sizeof(int8_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<int8_t> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(int8_t);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(int8_t));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int8_t query_value = atoi(term_value.c_str());
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -831,10 +838,16 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<int16_t> data;
data.resize(size / sizeof(int16_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<int16_t> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(int16_t);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(int16_t));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int16_t query_value = atoi(term_value.c_str());
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -852,10 +865,17 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<int32_t> data;
data.resize(size / sizeof(int32_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<int32_t> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(int32_t);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(int32_t));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int32_t query_value = atoi(term_value.c_str());
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -873,10 +893,17 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<int64_t> data;
data.resize(size / sizeof(int64_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<int64_t> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(int64_t);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(int64_t));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int64_t query_value = atoi(term_value.c_str());
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -894,12 +921,17 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<float> data;
data.resize(size / sizeof(float));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<float> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(float);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(int64_t));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
std::istringstream iss(term_value);
float query_value;
iss >> query_value;
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -917,12 +949,17 @@ ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_quer
std::vector<double> data;
data.resize(size / sizeof(double));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::vector<double> term_value;
auto term_size =
general_query->leaf->term_query->field_value.size() * (sizeof(int8_t)) / sizeof(double);
term_value.resize(term_size);
memcpy(term_value.data(), general_query->leaf->term_query->field_value.data(),
term_size * sizeof(double));
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
std::istringstream iss(term_value);
double query_value;
iss >> query_value;
for (auto query_value : term_value) {
if (data[i] == query_value) {
value_in_term = true;
break;
@ -1157,87 +1194,6 @@ ExecutionEngineImpl::Search(int64_t n, const uint8_t* data, int64_t k, const mil
return Status::OK();
}
Status
ExecutionEngineImpl::Search(int64_t n, const std::vector<int64_t>& ids, int64_t k, const milvus::json& extra_params,
float* distances, int64_t* labels, bool hybrid) {
TimeRecorder rc(LogOut("[%s][%ld] ExecutionEngineImpl::Search vector of ids", "search", 0));
if (index_ == nullptr) {
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld] ExecutionEngineImpl: index is null, failed to search", "search", 0);
return Status(DB_ERROR, "index is null");
}
milvus::json conf = extra_params;
conf[knowhere::meta::TOPK] = k;
auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
if (!adapter->CheckSearch(conf, index_->index_type(), index_->index_mode())) {
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld] Illegal search params", "search", 0);
throw Exception(DB_ERROR, "Illegal search params");
}
if (hybrid) {
HybridLoad();
}
rc.RecordSection("search prepare");
// std::string segment_dir;
// utils::GetParentPath(location_, segment_dir);
// segment::SegmentReader segment_reader(segment_dir);
// segment::IdBloomFilterPtr id_bloom_filter_ptr;
// segment_reader.LoadBloomFilter(id_bloom_filter_ptr);
// Check if the id is present. If so, find its offset
const std::vector<segment::doc_id_t>& uids = index_->GetUids();
std::vector<int64_t> offsets;
/*
std::vector<segment::doc_id_t> uids;
auto status = segment_reader.LoadUids(uids);
if (!status.ok()) {
return status;
}
*/
// There is only one id in ids
for (auto& id : ids) {
// if (id_bloom_filter_ptr->Check(id)) {
// if (uids.empty()) {
// segment_reader.LoadUids(uids);
// }
// auto found = std::find(uids.begin(), uids.end(), id);
// if (found != uids.end()) {
// auto offset = std::distance(uids.begin(), found);
// offsets.emplace_back(offset);
// }
// }
auto found = std::find(uids.begin(), uids.end(), id);
if (found != uids.end()) {
auto offset = std::distance(uids.begin(), found);
offsets.emplace_back(offset);
}
}
rc.RecordSection("get offset");
if (!offsets.empty()) {
auto dataset = knowhere::GenDatasetWithIds(offsets.size(), index_->Dim(), nullptr, offsets.data());
auto result = index_->QueryById(dataset, conf);
rc.RecordSection("query by id done");
LOG_ENGINE_DEBUG_ << LogOut("[%s][%ld] get %ld uids from index %s", "search", 0, index_->GetUids().size(),
location_.c_str());
MapAndCopyResult(result, uids, offsets.size(), k, distances, labels);
rc.RecordSection("map uids " + std::to_string(offsets.size() * k));
}
if (hybrid) {
HybridUnset();
}
return Status::OK();
}
Status
ExecutionEngineImpl::GetVectorByID(const int64_t& id, float* vector, bool hybrid) {
if (index_ == nullptr) {

View File

@ -82,10 +82,6 @@ class ExecutionEngineImpl : public ExecutionEngine {
Search(int64_t n, const uint8_t* data, int64_t k, const milvus::json& extra_params, float* distances,
int64_t* labels, bool hybrid = false) override;
Status
Search(int64_t n, const std::vector<int64_t>& ids, int64_t k, const milvus::json& extra_params, float* distances,
int64_t* labels, bool hybrid) override;
ExecutionEnginePtr
BuildIndex(const std::string& location, EngineType engine_type) override;

View File

@ -9,7 +9,7 @@
// 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 "db/insert/MemMenagerFactory.h"
#include "db/insert/MemManagerFactory.h"
#include "MemManagerImpl.h"
#include "utils/Exception.h"
#include "utils/Log.h"

View File

@ -97,6 +97,7 @@ MemManagerImpl::InsertEntities(const std::string& table_id, int64_t length, cons
<< "Insert buffer size exceeds limit. Performing force flush";
auto status = Flush(flushed_tables, false);
if (!status.ok()) {
LOG_ENGINE_DEBUG_ << LogOut("[%s][%ld] ", "insert", 0) << "Flush fail: " << status.message();
return status;
}
}

View File

@ -35,6 +35,9 @@
#include "utils/StringHelpFunctions.h"
#include "utils/ValidationUtil.h"
#define USING_SQLITE_WARNING LOG_ENGINE_WARNING_ << \
"You are using SQLite as the meta data management, which can't be used in production. Please change it to MySQL!";
namespace milvus {
namespace engine {
namespace meta {
@ -242,6 +245,7 @@ SqliteMetaImpl::Initialize() {
Status
SqliteMetaImpl::CreateCollection(CollectionSchema& collection_schema) {
USING_SQLITE_WARNING
try {
server::MetricCollector metric;
@ -436,6 +440,7 @@ SqliteMetaImpl::DeleteCollectionFiles(const std::string& collection_id) {
Status
SqliteMetaImpl::CreateCollectionFile(SegmentSchema& file_schema) {
USING_SQLITE_WARNING
if (file_schema.date_ == EmptyDate) {
file_schema.date_ = utils::GetDate();
}
@ -899,6 +904,7 @@ SqliteMetaImpl::DropCollectionIndex(const std::string& collection_id) {
Status
SqliteMetaImpl::CreatePartition(const std::string& collection_id, const std::string& partition_name, const std::string& tag,
uint64_t lsn) {
USING_SQLITE_WARNING
server::MetricCollector metric;
CollectionSchema collection_schema;
@ -1852,6 +1858,7 @@ SqliteMetaImpl::GetGlobalLastLSN(uint64_t& lsn) {
Status
SqliteMetaImpl::CreateHybridCollection(meta::CollectionSchema& collection_schema,
meta::hybrid::FieldsSchema& fields_schema) {
USING_SQLITE_WARNING
try {
server::MetricCollector metric;
@ -1912,7 +1919,6 @@ SqliteMetaImpl::CreateHybridCollection(meta::CollectionSchema& collection_schema
Status
SqliteMetaImpl::DescribeHybridCollection(milvus::engine::meta::CollectionSchema& collection_schema,
milvus::engine::meta::hybrid::FieldsSchema& fields_schema) {
try {
server::MetricCollector metric;
fiu_do_on("SqliteMetaImpl.DescriCollection.throw_exception", throw std::exception());
@ -1970,7 +1976,7 @@ SqliteMetaImpl::DescribeHybridCollection(milvus::engine::meta::CollectionSchema&
Status
SqliteMetaImpl::CreateHybridCollectionFile(SegmentSchema& file_schema) {
USING_SQLITE_WARNING
if (file_schema.date_ == EmptyDate) {
file_schema.date_ = utils::GetDate();
}

View File

@ -31,10 +31,11 @@ static const char* MilvusService_method_names[] = {
"/milvus.grpc.MilvusService/DescribeIndex",
"/milvus.grpc.MilvusService/DropIndex",
"/milvus.grpc.MilvusService/CreatePartition",
"/milvus.grpc.MilvusService/HasPartition",
"/milvus.grpc.MilvusService/ShowPartitions",
"/milvus.grpc.MilvusService/DropPartition",
"/milvus.grpc.MilvusService/Insert",
"/milvus.grpc.MilvusService/GetVectorByID",
"/milvus.grpc.MilvusService/GetVectorsByID",
"/milvus.grpc.MilvusService/GetVectorIDs",
"/milvus.grpc.MilvusService/Search",
"/milvus.grpc.MilvusService/SearchByID",
@ -78,33 +79,34 @@ MilvusService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& chan
, rpcmethod_DescribeIndex_(MilvusService_method_names[8], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropIndex_(MilvusService_method_names[9], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CreatePartition_(MilvusService_method_names[10], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowPartitions_(MilvusService_method_names[11], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropPartition_(MilvusService_method_names[12], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Insert_(MilvusService_method_names[13], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetVectorByID_(MilvusService_method_names[14], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetVectorIDs_(MilvusService_method_names[15], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Search_(MilvusService_method_names[16], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_SearchByID_(MilvusService_method_names[17], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_SearchInFiles_(MilvusService_method_names[18], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Cmd_(MilvusService_method_names[19], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteByID_(MilvusService_method_names[20], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadCollection_(MilvusService_method_names[21], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Flush_(MilvusService_method_names[22], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Compact_(MilvusService_method_names[23], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CreateHybridCollection_(MilvusService_method_names[24], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HasHybridCollection_(MilvusService_method_names[25], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropHybridCollection_(MilvusService_method_names[26], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DescribeHybridCollection_(MilvusService_method_names[27], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CountHybridCollection_(MilvusService_method_names[28], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollections_(MilvusService_method_names[29], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollectionInfo_(MilvusService_method_names[30], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadHybridCollection_(MilvusService_method_names[31], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_InsertEntity_(MilvusService_method_names[32], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearch_(MilvusService_method_names[33], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearchInSegments_(MilvusService_method_names[34], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityByID_(MilvusService_method_names[35], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityIDs_(MilvusService_method_names[36], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteEntitiesByID_(MilvusService_method_names[37], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HasPartition_(MilvusService_method_names[11], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowPartitions_(MilvusService_method_names[12], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropPartition_(MilvusService_method_names[13], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Insert_(MilvusService_method_names[14], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetVectorsByID_(MilvusService_method_names[15], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetVectorIDs_(MilvusService_method_names[16], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Search_(MilvusService_method_names[17], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_SearchByID_(MilvusService_method_names[18], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_SearchInFiles_(MilvusService_method_names[19], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Cmd_(MilvusService_method_names[20], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteByID_(MilvusService_method_names[21], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadCollection_(MilvusService_method_names[22], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Flush_(MilvusService_method_names[23], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Compact_(MilvusService_method_names[24], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CreateHybridCollection_(MilvusService_method_names[25], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HasHybridCollection_(MilvusService_method_names[26], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropHybridCollection_(MilvusService_method_names[27], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DescribeHybridCollection_(MilvusService_method_names[28], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CountHybridCollection_(MilvusService_method_names[29], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollections_(MilvusService_method_names[30], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollectionInfo_(MilvusService_method_names[31], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadHybridCollection_(MilvusService_method_names[32], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_InsertEntity_(MilvusService_method_names[33], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearch_(MilvusService_method_names[34], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearchInSegments_(MilvusService_method_names[35], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityByID_(MilvusService_method_names[36], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityIDs_(MilvusService_method_names[37], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteEntitiesByID_(MilvusService_method_names[38], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
{}
::grpc::Status MilvusService::Stub::CreateCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionSchema& request, ::milvus::grpc::Status* response) {
@ -415,6 +417,34 @@ void MilvusService::Stub::experimental_async::CreatePartition(::grpc::ClientCont
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_CreatePartition_, context, request, false);
}
::grpc::Status MilvusService::Stub::HasPartition(::grpc::ClientContext* context, const ::milvus::grpc::PartitionParam& request, ::milvus::grpc::BoolReply* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HasPartition_, context, request, response);
}
void MilvusService::Stub::experimental_async::HasPartition(::grpc::ClientContext* context, const ::milvus::grpc::PartitionParam* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasPartition_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasPartition(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasPartition_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasPartition(::grpc::ClientContext* context, const ::milvus::grpc::PartitionParam* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasPartition_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HasPartition(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasPartition_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::AsyncHasPartitionRaw(::grpc::ClientContext* context, const ::milvus::grpc::PartitionParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasPartition_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::PrepareAsyncHasPartitionRaw(::grpc::ClientContext* context, const ::milvus::grpc::PartitionParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasPartition_, context, request, false);
}
::grpc::Status MilvusService::Stub::ShowPartitions(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::PartitionList* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ShowPartitions_, context, request, response);
}
@ -499,32 +529,32 @@ void MilvusService::Stub::experimental_async::Insert(::grpc::ClientContext* cont
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::VectorIds>::Create(channel_.get(), cq, rpcmethod_Insert_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetVectorByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorIdentity& request, ::milvus::grpc::VectorData* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetVectorByID_, context, request, response);
::grpc::Status MilvusService::Stub::GetVectorsByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorsIdentity& request, ::milvus::grpc::VectorsData* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetVectorsByID_, context, request, response);
}
void MilvusService::Stub::experimental_async::GetVectorByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorIdentity* request, ::milvus::grpc::VectorData* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetVectorByID_, context, request, response, std::move(f));
void MilvusService::Stub::experimental_async::GetVectorsByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorsIdentity* request, ::milvus::grpc::VectorsData* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetVectorsByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetVectorByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::VectorData* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetVectorByID_, context, request, response, std::move(f));
void MilvusService::Stub::experimental_async::GetVectorsByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::VectorsData* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetVectorsByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetVectorByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorIdentity* request, ::milvus::grpc::VectorData* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetVectorByID_, context, request, response, reactor);
void MilvusService::Stub::experimental_async::GetVectorsByID(::grpc::ClientContext* context, const ::milvus::grpc::VectorsIdentity* request, ::milvus::grpc::VectorsData* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetVectorsByID_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::GetVectorByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::VectorData* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetVectorByID_, context, request, response, reactor);
void MilvusService::Stub::experimental_async::GetVectorsByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::VectorsData* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetVectorsByID_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::VectorData>* MilvusService::Stub::AsyncGetVectorByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::VectorIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::VectorData>::Create(channel_.get(), cq, rpcmethod_GetVectorByID_, context, request, true);
::grpc::ClientAsyncResponseReader< ::milvus::grpc::VectorsData>* MilvusService::Stub::AsyncGetVectorsByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::VectorsIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::VectorsData>::Create(channel_.get(), cq, rpcmethod_GetVectorsByID_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::VectorData>* MilvusService::Stub::PrepareAsyncGetVectorByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::VectorIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::VectorData>::Create(channel_.get(), cq, rpcmethod_GetVectorByID_, context, request, false);
::grpc::ClientAsyncResponseReader< ::milvus::grpc::VectorsData>* MilvusService::Stub::PrepareAsyncGetVectorsByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::VectorsIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::VectorsData>::Create(channel_.get(), cq, rpcmethod_GetVectorsByID_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetVectorIDs(::grpc::ClientContext* context, const ::milvus::grpc::GetVectorIDsParam& request, ::milvus::grpc::VectorIds* response) {
@ -1230,135 +1260,140 @@ MilvusService::Service::Service() {
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[11],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::PartitionParam, ::milvus::grpc::BoolReply>(
std::mem_fn(&MilvusService::Service::HasPartition), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[12],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::PartitionList>(
std::mem_fn(&MilvusService::Service::ShowPartitions), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[12],
MilvusService_method_names[13],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::PartitionParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DropPartition), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[13],
MilvusService_method_names[14],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::InsertParam, ::milvus::grpc::VectorIds>(
std::mem_fn(&MilvusService::Service::Insert), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[14],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::VectorIdentity, ::milvus::grpc::VectorData>(
std::mem_fn(&MilvusService::Service::GetVectorByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[15],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::VectorsIdentity, ::milvus::grpc::VectorsData>(
std::mem_fn(&MilvusService::Service::GetVectorsByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[16],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::GetVectorIDsParam, ::milvus::grpc::VectorIds>(
std::mem_fn(&MilvusService::Service::GetVectorIDs), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[16],
MilvusService_method_names[17],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::SearchParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::Search), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[17],
MilvusService_method_names[18],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::SearchByIDParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::SearchByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[18],
MilvusService_method_names[19],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::SearchInFilesParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::SearchInFiles), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[19],
MilvusService_method_names[20],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Command, ::milvus::grpc::StringReply>(
std::mem_fn(&MilvusService::Service::Cmd), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[20],
MilvusService_method_names[21],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::DeleteByIDParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DeleteByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[21],
MilvusService_method_names[22],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::PreloadCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[22],
MilvusService_method_names[23],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::FlushParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::Flush), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[23],
MilvusService_method_names[24],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::Compact), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[24],
MilvusService_method_names[25],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Mapping, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::CreateHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[25],
MilvusService_method_names[26],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::BoolReply>(
std::mem_fn(&MilvusService::Service::HasHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[26],
MilvusService_method_names[27],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DropHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[27],
MilvusService_method_names[28],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Mapping>(
std::mem_fn(&MilvusService::Service::DescribeHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[28],
MilvusService_method_names[29],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionRowCount>(
std::mem_fn(&MilvusService::Service::CountHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[29],
MilvusService_method_names[30],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Command, ::milvus::grpc::MappingList>(
std::mem_fn(&MilvusService::Service::ShowHybridCollections), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[30],
MilvusService_method_names[31],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionInfo>(
std::mem_fn(&MilvusService::Service::ShowHybridCollectionInfo), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[31],
MilvusService_method_names[32],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::PreloadHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[32],
MilvusService_method_names[33],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HInsertParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::InsertEntity), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[33],
MilvusService_method_names[34],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearch), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[34],
MilvusService_method_names[35],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchInSegmentsParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearchInSegments), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[35],
MilvusService_method_names[36],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HEntityIdentity, ::milvus::grpc::HEntity>(
std::mem_fn(&MilvusService::Service::GetEntityByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[36],
MilvusService_method_names[37],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HGetEntityIDsParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::GetEntityIDs), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[37],
MilvusService_method_names[38],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HDeleteByIDParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DeleteEntitiesByID), this)));
@ -1444,6 +1479,13 @@ MilvusService::Service::~Service() {
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HasPartition(::grpc::ServerContext* context, const ::milvus::grpc::PartitionParam* request, ::milvus::grpc::BoolReply* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::ShowPartitions(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::PartitionList* response) {
(void) context;
(void) request;
@ -1465,7 +1507,7 @@ MilvusService::Service::~Service() {
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::GetVectorByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorIdentity* request, ::milvus::grpc::VectorData* response) {
::grpc::Status MilvusService::Service::GetVectorsByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorsIdentity* request, ::milvus::grpc::VectorsData* response) {
(void) context;
(void) request;
(void) response;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -108,7 +108,7 @@ message SearchInFilesParam {
message SearchByIDParam {
string collection_name = 1;
repeated string partition_tag_array = 2;
int64 id = 3;
repeated int64 id_array = 3;
int64 topk = 4;
repeated KeyValuePair extra_params = 5;
}
@ -180,48 +180,28 @@ message DeleteByIDParam {
repeated int64 id_array = 2;
}
/**
* @brief segment statistics
*/
message SegmentStat {
string segment_name = 1;
int64 row_count = 2;
string index_name = 3;
int64 data_size = 4;
}
/**
* @brief collection statistics
*/
message PartitionStat {
string tag = 1;
int64 total_row_count = 2;
repeated SegmentStat segments_stat = 3;
}
/**
* @brief collection information
*/
message CollectionInfo {
Status status = 1;
int64 total_row_count = 2;
repeated PartitionStat partitions_stat = 3;
string json_info = 2;
}
/**
* @brief vector identity
* @brief vectors identity
*/
message VectorIdentity {
message VectorsIdentity {
string collection_name = 1;
int64 id = 2;
repeated int64 id_array = 2;
}
/**
* @brief vector data
*/
message VectorData {
message VectorsData {
Status status = 1;
RowRecord vector_data = 2;
repeated RowRecord vectors_data = 2;
}
/**
@ -307,9 +287,10 @@ message MappingList {
message TermQuery {
string field_name = 1;
repeated string values = 2;
float boost = 3;
repeated KeyValuePair extra_params = 4;
bytes values = 2;
int64 value_num = 3;
float boost = 4;
repeated KeyValuePair extra_params = 5;
}
enum CompareOperator {
@ -384,8 +365,9 @@ message HEntity {
Status status = 1;
int64 entity_id = 2;
repeated string field_names = 3;
repeated AttrRecord attr_records = 4;
repeated FieldValue result_values = 5;
bytes attr_records = 4;
int64 row_num = 5;
repeated FieldValue result_values = 6;
}
message HQueryResult {
@ -534,6 +516,15 @@ service MilvusService {
*/
rpc CreatePartition(PartitionParam) returns (Status) {}
/**
* @brief This method is used to test partition existence.
*
* @param PartitionParam, target partition.
*
* @return BoolReply
*/
rpc HasPartition(PartitionParam) returns (BoolReply) {}
/**
* @brief This method is used to show partition information
*
@ -562,13 +553,13 @@ service MilvusService {
rpc Insert(InsertParam) returns (VectorIds) {}
/**
* @brief This method is used to get vector data by id.
* @brief This method is used to get vectors data by id array.
*
* @param VectorIdentity, target vector id.
* @param VectorsIdentity, target vector id array.
*
* @return VectorData
* @return VectorsData
*/
rpc GetVectorByID(VectorIdentity) returns (VectorData) {}
rpc GetVectorsByID(VectorsIdentity) returns (VectorsData) {}
/**
* @brief This method is used to get vector ids from a segment

View File

@ -242,7 +242,7 @@ NSGConfAdapter::CheckSearch(Config& oricfg, const IndexType type, const IndexMod
bool
HNSWConfAdapter::CheckTrain(Config& oricfg, const IndexMode mode) {
static int64_t MIN_EFCONSTRUCTION = 100;
static int64_t MAX_EFCONSTRUCTION = 500;
static int64_t MAX_EFCONSTRUCTION = 800;
static int64_t MIN_M = 5;
static int64_t MAX_M = 48;

View File

@ -85,6 +85,7 @@ void
IndexAnnoy::BuildAll(const DatasetPtr& dataset_ptr, const Config& config) {
if (index_) {
// it is builded all
KNOWHERE_LOG_DEBUG << "IndexAnnoy::BuildAll: index_ has been built!";
return;
}

View File

@ -68,7 +68,7 @@ IndexHNSW::Load(const BinarySet& index_binary) {
index_ = std::make_shared<hnswlib::HierarchicalNSW<float>>(space);
index_->loadIndex(reader);
normalize = index_->metric_type_ == 1 ? true : false; // 1 == InnerProduct
normalize = index_->metric_type_ == 1; // 1 == InnerProduct
} catch (std::exception& e) {
KNOWHERE_THROW_MSG(e.what());
}
@ -158,7 +158,7 @@ IndexHNSW::Query(const DatasetPtr& dataset_ptr, const Config& config) {
ret = index_->searchKnn((float*)single_query, k, compare, blacklist);
while (ret.size() < k) {
ret.push_back(std::make_pair(-1, -1));
ret.emplace_back(std::make_pair(-1, -1));
}
std::vector<float> dist;
std::vector<int64_t> ids;

View File

@ -121,11 +121,6 @@ CPUSPTAGRNG::Train(const DatasetPtr& origin, const Config& train_config) {
DatasetPtr dataset = origin;
// if (index_ptr_->GetDistCalcMethod() == SPTAG::DistCalcMethod::Cosine
// && preprocessor_) {
// preprocessor_->Preprocess(dataset);
//}
auto vectorset = ConvertToVectorSet(dataset);
auto metaset = ConvertToMetadataSet(dataset);
index_ptr_->BuildIndex(vectorset, metaset);

View File

@ -55,6 +55,23 @@ static std::unordered_map<std::string, int32_t> str_old_index_type_map = {
{IndexEnum::INDEX_FAISS_BIN_IVFFLAT, (int32_t)OldIndexType::FAISS_BIN_IVFLAT_CPU},
};
/* used in 0.8.0 */
namespace IndexEnum {
const char* INVALID = "";
const char* INDEX_FAISS_IDMAP = "IDMAP";
const char* INDEX_FAISS_IVFFLAT = "IVF_FLAT";
const char* INDEX_FAISS_IVFPQ = "IVF_PQ";
const char* INDEX_FAISS_IVFSQ8 = "IVF_SQ8";
const char* INDEX_FAISS_IVFSQ8H = "IVF_SQ8_HYBRID";
const char* INDEX_FAISS_BIN_IDMAP = "BIN_IDMAP";
const char* INDEX_FAISS_BIN_IVFFLAT = "BIN_IVF_FLAT";
const char* INDEX_NSG = "NSG";
const char* INDEX_SPTAG_KDT_RNT = "SPTAG_KDT_RNT";
const char* INDEX_SPTAG_BKT_RNT = "SPTAG_BKT_RNT";
const char* INDEX_HNSW = "HNSW";
const char* INDEX_ANNOY = "ANNOY";
} // namespace IndexEnum
std::string
OldIndexTypeToStr(const int32_t type) {
try {

View File

@ -43,19 +43,19 @@ using IndexType = std::string;
/* used in 0.8.0 */
namespace IndexEnum {
constexpr const char* INVALID = "";
constexpr const char* INDEX_FAISS_IDMAP = "IDMAP";
constexpr const char* INDEX_FAISS_IVFFLAT = "IVF_FLAT";
constexpr const char* INDEX_FAISS_IVFPQ = "IVF_PQ";
constexpr const char* INDEX_FAISS_IVFSQ8 = "IVF_SQ8";
constexpr const char* INDEX_FAISS_IVFSQ8H = "IVF_SQ8_HYBRID";
constexpr const char* INDEX_FAISS_BIN_IDMAP = "BIN_IDMAP";
constexpr const char* INDEX_FAISS_BIN_IVFFLAT = "BIN_IVF_FLAT";
constexpr const char* INDEX_NSG = "NSG";
constexpr const char* INDEX_SPTAG_KDT_RNT = "SPTAG_KDT_RNT";
constexpr const char* INDEX_SPTAG_BKT_RNT = "SPTAG_BKT_RNT";
constexpr const char* INDEX_HNSW = "HNSW";
constexpr const char* INDEX_ANNOY = "ANNOY";
extern const char* INVALID;
extern const char* INDEX_FAISS_IDMAP;
extern const char* INDEX_FAISS_IVFFLAT;
extern const char* INDEX_FAISS_IVFPQ;
extern const char* INDEX_FAISS_IVFSQ8;
extern const char* INDEX_FAISS_IVFSQ8H;
extern const char* INDEX_FAISS_BIN_IDMAP;
extern const char* INDEX_FAISS_BIN_IVFFLAT;
extern const char* INDEX_NSG;
extern const char* INDEX_SPTAG_KDT_RNT;
extern const char* INDEX_SPTAG_BKT_RNT;
extern const char* INDEX_HNSW;
extern const char* INDEX_ANNOY;
} // namespace IndexEnum
enum class IndexMode { MODE_CPU = 0, MODE_GPU = 1 };

View File

@ -63,13 +63,13 @@ namespace SPTAG
static double GetVector(char* cstr, const char* sep, std::vector<float>& arr, DimensionType& NumDim) {
char* current;
char* context = NULL;
char* context = nullptr;
DimensionType i = 0;
double sum = 0;
arr.clear();
current = strtok_s(cstr, sep, &context);
while (current != NULL && (i < NumDim || NumDim < 0)) {
while (current != nullptr && (i < NumDim || NumDim < 0)) {
try {
float val = (float)atof(current);
arr.push_back(val);
@ -80,7 +80,7 @@ namespace SPTAG
}
sum += arr[i] * arr[i];
current = strtok_s(NULL, sep, &context);
current = strtok_s(nullptr, sep, &context);
i++;
}

View File

@ -44,10 +44,10 @@ class AnnoyIndex {
ptr->get_nns_by_vector(w, n, search_k, result, distances);
};
void getNnsByItem(int item, int n, int search_k, vector<int32_t>* result) {
ptr->get_nns_by_item(item, n, search_k, result, NULL);
ptr->get_nns_by_item(item, n, search_k, result, nullptr);
};
void getNnsByVector(const float* w, int n, int search_k, vector<int32_t>* result) {
ptr->get_nns_by_vector(w, n, search_k, result, NULL);
ptr->get_nns_by_vector(w, n, search_k, result, nullptr);
};
int getNItems() {

View File

@ -824,19 +824,19 @@ struct Manhattan : Minkowski {
template<typename S, typename T>
class AnnoyIndexInterface {
public:
// Note that the methods with an **error argument will allocate memory and write the pointer to that string if error is non-NULL
// Note that the methods with an **error argument will allocate memory and write the pointer to that string if error is non-nullptr
virtual ~AnnoyIndexInterface() {};
virtual bool add_item(S item, const T* w, char** error=NULL) = 0;
virtual bool build(int q, char** error=NULL) = 0;
virtual bool unbuild(char** error=NULL) = 0;
virtual bool save(const char* filename, bool prefault=false, char** error=NULL) = 0;
virtual bool add_item(S item, const T* w, char** error=nullptr) = 0;
virtual bool build(int q, char** error=nullptr) = 0;
virtual bool unbuild(char** error=nullptr) = 0;
virtual bool save(const char* filename, bool prefault=false, char** error=nullptr) = 0;
virtual void unload() = 0;
virtual bool load(const char* filename, bool prefault=false, char** error=NULL) = 0;
virtual bool load_index(void* index_data, const int64_t& index_size, char** error = NULL) = 0;
virtual bool load(const char* filename, bool prefault=false, char** error=nullptr) = 0;
virtual bool load_index(void* index_data, const int64_t& index_size, char** error = nullptr) = 0;
virtual T get_distance(S i, S j) const = 0;
virtual void get_nns_by_item(S item, size_t n, int search_k, vector<S>* result, vector<T>* distances,
virtual void get_nns_by_item(S item, size_t n, int64_t search_k, vector<S>* result, vector<T>* distances,
faiss::ConcurrentBitsetPtr& bitset = nullptr) const = 0;
virtual void get_nns_by_vector(const T* w, size_t n, int search_k, vector<S>* result, vector<T>* distances,
virtual void get_nns_by_vector(const T* w, size_t n, int64_t search_k, vector<S>* result, vector<T>* distances,
faiss::ConcurrentBitsetPtr& bitset = nullptr) const = 0;
virtual S get_n_items() const = 0;
virtual S get_dim() const = 0;
@ -846,7 +846,7 @@ class AnnoyIndexInterface {
virtual void verbose(bool v) = 0;
virtual void get_item(S item, T* v) const = 0;
virtual void set_seed(int q) = 0;
virtual bool on_disk_build(const char* filename, char** error=NULL) = 0;
virtual bool on_disk_build(const char* filename, char** error=nullptr) = 0;
};
template<typename S, typename T, typename Distance, typename Random>
@ -894,12 +894,12 @@ public:
return _f;
}
bool add_item(S item, const T* w, char** error=NULL) {
bool add_item(S item, const T* w, char** error=nullptr) {
return add_item_impl(item, w, error);
}
template<typename W>
bool add_item_impl(S item, const W& w, char** error=NULL) {
bool add_item_impl(S item, const W& w, char** error=nullptr) {
if (_loaded) {
set_error_from_string(error, "You can't add an item to a loaded index");
return false;
@ -924,7 +924,7 @@ public:
return true;
}
bool on_disk_build(const char* file, char** error=NULL) {
bool on_disk_build(const char* file, char** error=nullptr) {
_on_disk = true;
_fd = open(file, O_RDWR | O_CREAT | O_TRUNC, (int) 0600);
if (_fd == -1) {
@ -945,7 +945,7 @@ public:
return true;
}
bool build(int q, char** error=NULL) {
bool build(int q, char** error=nullptr) {
if (_loaded) {
set_error_from_string(error, "You can't build a loaded index");
return false;
@ -997,7 +997,7 @@ public:
return true;
}
bool unbuild(char** error=NULL) {
bool unbuild(char** error=nullptr) {
if (_loaded) {
set_error_from_string(error, "You can't unbuild a loaded index");
return false;
@ -1010,7 +1010,7 @@ public:
return true;
}
bool save(const char* filename, bool prefault=false, char** error=NULL) {
bool save(const char* filename, bool prefault=false, char** error=nullptr) {
if (!_built) {
set_error_from_string(error, "You can't save an index that hasn't been built");
return false;
@ -1022,7 +1022,7 @@ public:
unlink(filename);
FILE *f = fopen(filename, "wb");
if (f == NULL) {
if (f == nullptr) {
set_error_from_errno(error, "Unable to open");
return false;
}
@ -1044,7 +1044,7 @@ public:
void reinitialize() {
_fd = 0;
_nodes = NULL;
_nodes = nullptr;
_loaded = false;
_n_items = 0;
_n_nodes = 0;
@ -1071,7 +1071,7 @@ public:
if (_verbose) showUpdate("unloaded\n");
}
bool load(const char* filename, bool prefault=false, char** error=NULL) {
bool load(const char* filename, bool prefault=false, char** error=nullptr) {
_fd = open(filename, O_RDONLY, (int)0400);
if (_fd == -1) {
set_error_from_errno(error, "Unable to open");
@ -1172,14 +1172,14 @@ public:
return D::normalized_distance(D::distance(_get(i), _get(j), _f));
}
void get_nns_by_item(S item, size_t n, int search_k, vector<S>* result, vector<T>* distances,
void get_nns_by_item(S item, size_t n, int64_t search_k, vector<S>* result, vector<T>* distances,
faiss::ConcurrentBitsetPtr& bitset) const {
// TODO: handle OOB
const Node* m = _get(item);
_get_all_nns(m->v, n, search_k, result, distances, bitset);
}
void get_nns_by_vector(const T* w, size_t n, int search_k, vector<S>* result, vector<T>* distances,
void get_nns_by_vector(const T* w, size_t n, int64_t search_k, vector<S>* result, vector<T>* distances,
faiss::ConcurrentBitsetPtr& bitset) const {
_get_all_nns(w, n, search_k, result, distances, bitset);
}
@ -1327,7 +1327,7 @@ protected:
return item;
}
void _get_all_nns(const T* v, size_t n, int search_k, vector<S>* result, vector<T>* distances,
void _get_all_nns(const T* v, size_t n, int64_t search_k, vector<S>* result, vector<T>* distances,
faiss::ConcurrentBitsetPtr& bitset) const {
Node* v_node = (Node *)alloca(_s);
D::template zero_value<Node>(v_node);
@ -1337,7 +1337,7 @@ protected:
std::priority_queue<pair<T, S> > q;
if (search_k <= 0) {
search_k = std::max(n * _roots.size(), (size_t )_n_items * 5 / 100);
search_k = std::max(int64_t(n * _roots.size()), int64_t(_n_items * 5 / 100));
}
for (size_t i = 0; i < _roots.size(); i++) {

View File

@ -21,7 +21,7 @@
#include "kissrandom.h"
#if LUA_VERSION_NUM == 501
#define compat_setfuncs(L, funcs) luaL_register(L, NULL, funcs)
#define compat_setfuncs(L, funcs) luaL_register(L, nullptr, funcs)
#define compat_rawlen lua_objlen
#else
#define compat_setfuncs(L, funcs) luaL_setfuncs(L, funcs, 0)
@ -203,7 +203,7 @@ public:
Searcher s(L);
int item = getItemIndex(L, 2, s.self->get_n_items());
s.self->get_nns_by_item(item, s.n, s.search_k, &s.result,
s.include_distances ? &s.distances : NULL);
s.include_distances ? &s.distances : nullptr);
return s.pushResults(L);
}
@ -213,7 +213,7 @@ public:
AnnoyT* vec = &(_vec[0]);
toVector(L, 2, s.self->get_f(), vec);
s.self->get_nns_by_vector(vec, s.n, s.search_k, &s.result,
s.include_distances ? &s.distances : NULL);
s.include_distances ? &s.distances : nullptr);
return s.pushResults(L);
}
@ -246,7 +246,7 @@ public:
static const luaL_Reg funcs[] = {
{"__gc", &ThisClass::gc},
{"__tostring", &ThisClass::tostring},
{NULL, NULL},
{nullptr, nullptr},
};
return funcs;
}
@ -264,7 +264,7 @@ public:
{"get_distance", &ThisClass::get_distance},
{"get_n_items", &ThisClass::get_n_items},
{"on_disk_build", &ThisClass::on_disk_build},
{NULL, NULL},
{nullptr, nullptr},
};
return funcs;
}
@ -304,7 +304,7 @@ static int lua_an_make(lua_State* L) {
static const luaL_Reg LUA_ANNOY_FUNCS[] = {
{"AnnoyIndex", lua_an_make},
{NULL, NULL},
{nullptr, nullptr},
};
extern "C" {

View File

@ -96,7 +96,7 @@ public:
_index.get_nns_by_item(item, n, search_k, result, &distances_internal);
distances->insert(distances->begin(), distances_internal.begin(), distances_internal.end());
} else {
_index.get_nns_by_item(item, n, search_k, result, NULL);
_index.get_nns_by_item(item, n, search_k, result, nullptr);
}
};
void get_nns_by_vector(const float* w, size_t n, int search_k, vector<int32_t>* result, vector<float>* distances) const {
@ -107,7 +107,7 @@ public:
_index.get_nns_by_vector(&w_internal[0], n, search_k, result, &distances_internal);
distances->insert(distances->begin(), distances_internal.begin(), distances_internal.end());
} else {
_index.get_nns_by_vector(&w_internal[0], n, search_k, result, NULL);
_index.get_nns_by_vector(&w_internal[0], n, search_k, result, nullptr);
}
};
int32_t get_n_items() const { return _index.get_n_items(); };
@ -133,14 +133,14 @@ typedef struct {
static PyObject *
py_an_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
py_annoy *self = (py_annoy *)type->tp_alloc(type, 0);
if (self == NULL) {
return NULL;
if (self == nullptr) {
return nullptr;
}
const char *metric = NULL;
const char *metric = nullptr;
static char const * kwlist[] = {"f", "metric", NULL};
static char const * kwlist[] = {"f", "metric", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s", (char**)kwlist, &self->f, &metric))
return NULL;
return nullptr;
if (!metric) {
// This keeps coming up, see #368 etc
PyErr_WarnEx(PyExc_FutureWarning, "The default argument for metric will be removed "
@ -158,7 +158,7 @@ py_an_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
self->ptr = new AnnoyIndex<int32_t, float, DotProduct, Kiss64Random>(self->f);
} else {
PyErr_SetString(PyExc_ValueError, "No such metric");
return NULL;
return nullptr;
}
return (PyObject *)self;
@ -168,11 +168,11 @@ py_an_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
static int
py_an_init(py_annoy *self, PyObject *args, PyObject *kwargs) {
// Seems to be needed for Python 3
const char *metric = NULL;
const char *metric = nullptr;
int f;
static char const * kwlist[] = {"f", "metric", NULL};
static char const * kwlist[] = {"f", "metric", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s", (char**)kwlist, &f, &metric))
return (int) NULL;
return (int) nullptr;
return 0;
}
@ -187,7 +187,7 @@ py_an_dealloc(py_annoy* self) {
static PyMemberDef py_annoy_members[] = {
{(char*)"f", T_INT, offsetof(py_annoy, f), 0,
(char*)""},
{NULL} /* Sentinel */
{nullptr} /* Sentinel */
};
@ -196,15 +196,15 @@ py_an_load(py_annoy *self, PyObject *args, PyObject *kwargs) {
char *filename, *error;
bool prefault = false;
if (!self->ptr)
return NULL;
static char const * kwlist[] = {"fn", "prefault", NULL};
return nullptr;
static char const * kwlist[] = {"fn", "prefault", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|b", (char**)kwlist, &filename, &prefault))
return NULL;
return nullptr;
if (!self->ptr->load(filename, prefault, &error)) {
PyErr_SetString(PyExc_IOError, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_TRUE;
}
@ -215,15 +215,15 @@ py_an_save(py_annoy *self, PyObject *args, PyObject *kwargs) {
char *filename, *error;
bool prefault = false;
if (!self->ptr)
return NULL;
static char const * kwlist[] = {"fn", "prefault", NULL};
return nullptr;
static char const * kwlist[] = {"fn", "prefault", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|b", (char**)kwlist, &filename, &prefault))
return NULL;
return nullptr;
if (!self->ptr->save(filename, prefault, &error)) {
PyErr_SetString(PyExc_IOError, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_TRUE;
}
@ -265,21 +265,21 @@ static PyObject*
py_an_get_nns_by_item(py_annoy *self, PyObject *args, PyObject *kwargs) {
int32_t item, n, search_k=-1, include_distances=0;
if (!self->ptr)
return NULL;
return nullptr;
static char const * kwlist[] = {"i", "n", "search_k", "include_distances", NULL};
static char const * kwlist[] = {"i", "n", "search_k", "include_distances", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", (char**)kwlist, &item, &n, &search_k, &include_distances))
return NULL;
return nullptr;
if (!check_constraints(self, item, false)) {
return NULL;
return nullptr;
}
vector<int32_t> result;
vector<float> distances;
Py_BEGIN_ALLOW_THREADS;
self->ptr->get_nns_by_item(item, n, search_k, &result, include_distances ? &distances : NULL);
self->ptr->get_nns_by_item(item, n, search_k, &result, include_distances ? &distances : nullptr);
Py_END_ALLOW_THREADS;
return get_nns_to_python(result, distances, include_distances);
@ -315,22 +315,22 @@ py_an_get_nns_by_vector(py_annoy *self, PyObject *args, PyObject *kwargs) {
PyObject* v;
int32_t n, search_k=-1, include_distances=0;
if (!self->ptr)
return NULL;
return nullptr;
static char const * kwlist[] = {"vector", "n", "search_k", "include_distances", NULL};
static char const * kwlist[] = {"vector", "n", "search_k", "include_distances", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii", (char**)kwlist, &v, &n, &search_k, &include_distances))
return NULL;
return nullptr;
vector<float> w(self->f);
if (!convert_list_to_vector(v, self->f, &w)) {
return NULL;
return nullptr;
}
vector<int32_t> result;
vector<float> distances;
Py_BEGIN_ALLOW_THREADS;
self->ptr->get_nns_by_vector(&w[0], n, search_k, &result, include_distances ? &distances : NULL);
self->ptr->get_nns_by_vector(&w[0], n, search_k, &result, include_distances ? &distances : nullptr);
Py_END_ALLOW_THREADS;
return get_nns_to_python(result, distances, include_distances);
@ -341,12 +341,12 @@ static PyObject*
py_an_get_item_vector(py_annoy *self, PyObject *args) {
int32_t item;
if (!self->ptr)
return NULL;
return nullptr;
if (!PyArg_ParseTuple(args, "i", &item))
return NULL;
return nullptr;
if (!check_constraints(self, item, false)) {
return NULL;
return nullptr;
}
vector<float> v(self->f);
@ -365,24 +365,24 @@ py_an_add_item(py_annoy *self, PyObject *args, PyObject* kwargs) {
PyObject* v;
int32_t item;
if (!self->ptr)
return NULL;
static char const * kwlist[] = {"i", "vector", NULL};
return nullptr;
static char const * kwlist[] = {"i", "vector", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO", (char**)kwlist, &item, &v))
return NULL;
return nullptr;
if (!check_constraints(self, item, true)) {
return NULL;
return nullptr;
}
vector<float> w(self->f);
if (!convert_list_to_vector(v, self->f, &w)) {
return NULL;
return nullptr;
}
char* error;
if (!self->ptr->add_item(item, &w[0], &error)) {
PyErr_SetString(PyExc_Exception, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_NONE;
@ -392,15 +392,15 @@ static PyObject *
py_an_on_disk_build(py_annoy *self, PyObject *args, PyObject *kwargs) {
char *filename, *error;
if (!self->ptr)
return NULL;
static char const * kwlist[] = {"fn", NULL};
return nullptr;
static char const * kwlist[] = {"fn", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", (char**)kwlist, &filename))
return NULL;
return nullptr;
if (!self->ptr->on_disk_build(filename, &error)) {
PyErr_SetString(PyExc_IOError, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_TRUE;
}
@ -409,10 +409,10 @@ static PyObject *
py_an_build(py_annoy *self, PyObject *args, PyObject *kwargs) {
int q;
if (!self->ptr)
return NULL;
static char const * kwlist[] = {"n_trees", NULL};
return nullptr;
static char const * kwlist[] = {"n_trees", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", (char**)kwlist, &q))
return NULL;
return nullptr;
bool res;
char* error;
@ -422,7 +422,7 @@ py_an_build(py_annoy *self, PyObject *args, PyObject *kwargs) {
if (!res) {
PyErr_SetString(PyExc_Exception, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_TRUE;
@ -432,13 +432,13 @@ py_an_build(py_annoy *self, PyObject *args, PyObject *kwargs) {
static PyObject *
py_an_unbuild(py_annoy *self) {
if (!self->ptr)
return NULL;
return nullptr;
char* error;
if (!self->ptr->unbuild(&error)) {
PyErr_SetString(PyExc_Exception, error);
free(error);
return NULL;
return nullptr;
}
Py_RETURN_TRUE;
@ -448,7 +448,7 @@ py_an_unbuild(py_annoy *self) {
static PyObject *
py_an_unload(py_annoy *self) {
if (!self->ptr)
return NULL;
return nullptr;
self->ptr->unload();
@ -460,12 +460,12 @@ static PyObject *
py_an_get_distance(py_annoy *self, PyObject *args) {
int32_t i, j;
if (!self->ptr)
return NULL;
return nullptr;
if (!PyArg_ParseTuple(args, "ii", &i, &j))
return NULL;
return nullptr;
if (!check_constraints(self, i, false) || !check_constraints(self, j, false)) {
return NULL;
return nullptr;
}
double d = self->ptr->get_distance(i,j);
@ -476,7 +476,7 @@ py_an_get_distance(py_annoy *self, PyObject *args) {
static PyObject *
py_an_get_n_items(py_annoy *self) {
if (!self->ptr)
return NULL;
return nullptr;
int32_t n = self->ptr->get_n_items();
return PyInt_FromLong(n);
@ -485,7 +485,7 @@ py_an_get_n_items(py_annoy *self) {
static PyObject *
py_an_get_n_trees(py_annoy *self) {
if (!self->ptr)
return NULL;
return nullptr;
int32_t n = self->ptr->get_n_trees();
return PyInt_FromLong(n);
@ -495,9 +495,9 @@ static PyObject *
py_an_verbose(py_annoy *self, PyObject *args) {
int verbose;
if (!self->ptr)
return NULL;
return nullptr;
if (!PyArg_ParseTuple(args, "i", &verbose))
return NULL;
return nullptr;
self->ptr->verbose((bool)verbose);
@ -509,9 +509,9 @@ static PyObject *
py_an_set_seed(py_annoy *self, PyObject *args) {
int q;
if (!self->ptr)
return NULL;
return nullptr;
if (!PyArg_ParseTuple(args, "i", &q))
return NULL;
return nullptr;
self->ptr->set_seed(q);
@ -535,12 +535,12 @@ static PyMethodDef AnnoyMethods[] = {
{"get_n_trees",(PyCFunction)py_an_get_n_trees, METH_NOARGS, "Returns the number of trees in the index."},
{"verbose",(PyCFunction)py_an_verbose, METH_VARARGS, ""},
{"set_seed",(PyCFunction)py_an_set_seed, METH_VARARGS, "Sets the seed of Annoy's random number generator."},
{NULL, NULL, 0, NULL} /* Sentinel */
{nullptr, nullptr, 0, nullptr} /* Sentinel */
};
static PyTypeObject PyAnnoyType = {
PyVarObject_HEAD_INIT(NULL, 0)
PyVarObject_HEAD_INIT(nullptr, 0)
"annoy.Annoy", /*tp_name*/
sizeof(py_annoy), /*tp_basicsize*/
0, /*tp_itemsize*/
@ -581,7 +581,7 @@ static PyTypeObject PyAnnoyType = {
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
{nullptr} /* Sentinel */
};
#if PY_MAJOR_VERSION >= 3
@ -591,10 +591,10 @@ static PyMethodDef module_methods[] = {
ANNOY_DOC, /* m_doc */
-1, /* m_size */
module_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
nullptr, /* m_reload */
nullptr, /* m_traverse */
nullptr, /* m_clear */
nullptr, /* m_free */
};
#endif
@ -602,7 +602,7 @@ PyObject *create_module(void) {
PyObject *m;
if (PyType_Ready(&PyAnnoyType) < 0)
return NULL;
return nullptr;
#if PY_MAJOR_VERSION >= 3
m = PyModule_Create(&moduledef);
@ -610,8 +610,8 @@ PyObject *create_module(void) {
m = Py_InitModule("annoylib", module_methods);
#endif
if (m == NULL)
return NULL;
if (m == nullptr)
return nullptr;
Py_INCREF(&PyAnnoyType);
PyModule_AddObject(m, "Annoy", (PyObject *)&PyAnnoyType);

View File

@ -13,9 +13,9 @@
namespace faiss { namespace gpu {
DeviceMemoryReservation::DeviceMemoryReservation()
: state_(NULL),
: state_(nullptr),
device_(0),
data_(NULL),
data_(nullptr),
size_(0),
stream_(0) {
}
@ -41,7 +41,7 @@ DeviceMemoryReservation::DeviceMemoryReservation(
size_ = m.size_;
stream_ = m.stream_;
m.data_ = NULL;
m.data_ = nullptr;
}
DeviceMemoryReservation::~DeviceMemoryReservation() {
@ -50,7 +50,7 @@ DeviceMemoryReservation::~DeviceMemoryReservation() {
state_->returnAllocation(*this);
}
data_ = NULL;
data_ = nullptr;
}
DeviceMemoryReservation&
@ -66,7 +66,7 @@ DeviceMemoryReservation::operator=(DeviceMemoryReservation&& m) {
size_ = m.size_;
stream_ = m.stream_;
m.data_ = NULL;
m.data_ = nullptr;
return *this;
}

View File

@ -94,7 +94,7 @@ hdf5_read(const std::string& file_name, const std::string& dataset_name, H5T_cla
assert(t_class == dataset_class || !"Illegal dataset class type");
dataspace = H5Dget_space(dataset); /* dataspace handle */
H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
H5Sget_simple_extent_dims(dataspace, dims_out, nullptr);
n_out = dims_out[0];
d_out = dims_out[1];
@ -102,20 +102,20 @@ hdf5_read(const std::string& file_name, const std::string& dataset_name, H5T_cla
offset[0] = offset[1] = 0;
count[0] = dims_out[0];
count[1] = dims_out[1];
H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, count, NULL);
H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, nullptr, count, nullptr);
/* Define the memory dataspace. */
dimsm[0] = dims_out[0];
dimsm[1] = dims_out[1];
dimsm[2] = 1;
memspace = H5Screate_simple(3, dimsm, NULL);
memspace = H5Screate_simple(3, dimsm, nullptr);
/* Define memory hyperslab. */
offset_out[0] = offset_out[1] = offset_out[2] = 0;
count_out[0] = dims_out[0];
count_out[1] = dims_out[1];
count_out[2] = 1;
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL, count_out, NULL);
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, nullptr, count_out, nullptr);
/* Read data from hyperslab in the file into the hyperslab in memory and display. */
switch (t_class) {

View File

@ -102,7 +102,7 @@ hdf5_read(const std::string& file_name, const std::string& dataset_name, H5T_cla
assert(t_class == dataset_class || !"Illegal dataset class type");
dataspace = H5Dget_space(dataset); /* dataspace handle */
H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
H5Sget_simple_extent_dims(dataspace, dims_out, nullptr);
n_out = dims_out[0];
d_out = dims_out[1];
@ -110,20 +110,20 @@ hdf5_read(const std::string& file_name, const std::string& dataset_name, H5T_cla
offset[0] = offset[1] = 0;
count[0] = dims_out[0];
count[1] = dims_out[1];
H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, count, NULL);
H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, nullptr, count, nullptr);
/* Define the memory dataspace. */
dimsm[0] = dims_out[0];
dimsm[1] = dims_out[1];
dimsm[2] = 1;
memspace = H5Screate_simple(3, dimsm, NULL);
memspace = H5Screate_simple(3, dimsm, nullptr);
/* Define memory hyperslab. */
offset_out[0] = offset_out[1] = offset_out[2] = 0;
count_out[0] = dims_out[0];
count_out[1] = dims_out[1];
count_out[2] = 1;
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL, count_out, NULL);
H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, nullptr, count_out, nullptr);
/* Read data from hyperslab in the file into the hyperslab in memory and display. */
switch (t_class) {

View File

@ -219,8 +219,8 @@ main() {
}
printf("gen xb and ids done! \n");
// srand((unsigned)time(NULL));
auto random_seed = (unsigned)time(NULL);
// srand((unsigned)time(nullptr));
auto random_seed = (unsigned)time(nullptr);
printf("delete ids: \n");
for (int i = 0; i < nq; i++) {
auto tmp = rand_r(&random_seed) % nb;

View File

@ -154,8 +154,8 @@ main() {
}
// printf("gen xb and ids done! \n");
// srand((unsigned)time(NULL));
auto random_seed = (unsigned)time(NULL);
// srand((unsigned)time(nullptr));
auto random_seed = (unsigned)time(nullptr);
// printf("delete ids: \n");
for (int i = 0; i < nq; i++) {
auto tmp = rand_r(&random_seed) % nb;

View File

@ -29,22 +29,22 @@ TEST_F(KnowhereTest, KNOWHERE_RESOURCE_TEST) {
#ifdef MILVUS_GPU_VERSION
fiu_init(0);
fiu_enable("check_config_gpu_resource_enable_fail", 1, NULL, 0);
fiu_enable("check_config_gpu_resource_enable_fail", 1, nullptr, 0);
s = milvus::engine::KnowhereResource::Initialize();
ASSERT_FALSE(s.ok());
fiu_disable("check_config_gpu_resource_enable_fail");
fiu_enable("KnowhereResource.Initialize.disable_gpu", 1, NULL, 0);
fiu_enable("KnowhereResource.Initialize.disable_gpu", 1, nullptr, 0);
s = milvus::engine::KnowhereResource::Initialize();
ASSERT_TRUE(s.ok());
fiu_disable("KnowhereResource.Initialize.disable_gpu");
fiu_enable("check_gpu_resource_config_build_index_fail", 1, NULL, 0);
fiu_enable("check_gpu_resource_config_build_index_fail", 1, nullptr, 0);
s = milvus::engine::KnowhereResource::Initialize();
ASSERT_FALSE(s.ok());
fiu_disable("check_gpu_resource_config_build_index_fail");
fiu_enable("check_gpu_resource_config_search_fail", 1, NULL, 0);
fiu_enable("check_gpu_resource_config_search_fail", 1, nullptr, 0);
s = milvus::engine::KnowhereResource::Initialize();
ASSERT_FALSE(s.ok());
fiu_disable("check_gpu_resource_config_search_fail");

View File

@ -115,35 +115,35 @@ TEST_P(KnowhereWrapperTest, BASE_TEST) {
index_->GetDeviceId();
fiu_init(0);
fiu_enable("VecIndexImpl.BuildAll.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("BFIndex.BuildAll.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("IVFMixIndex.BuildAll.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.BuildAll.throw_knowhere_exception", 1, nullptr, 0);
fiu_enable("BFIndex.BuildAll.throw_knowhere_exception", 1, nullptr, 0);
fiu_enable("IVFMixIndex.BuildAll.throw_knowhere_exception", 1, nullptr, 0);
auto s = index_->BuildAll(nb, xb.data(), ids.data(), conf);
fiu_disable("IVFMixIndex.BuildAll.throw_knowhere_exception");
fiu_disable("BFIndex.BuildAll.throw_knowhere_exception");
fiu_disable("VecIndexImpl.BuildAll.throw_knowhere_exception");
fiu_enable("VecIndexImpl.BuildAll.throw_std_exception", 1, NULL, 0);
fiu_enable("BFIndex.BuildAll.throw_std_exception", 1, NULL, 0);
fiu_enable("IVFMixIndex.BuildAll.throw_std_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.BuildAll.throw_std_exception", 1, nullptr, 0);
fiu_enable("BFIndex.BuildAll.throw_std_exception", 1, nullptr, 0);
fiu_enable("IVFMixIndex.BuildAll.throw_std_exception", 1, nullptr, 0);
s = index_->BuildAll(nb, xb.data(), ids.data(), conf);
fiu_disable("IVFMixIndex.BuildAll.throw_std_exception");
fiu_disable("BFIndex.BuildAll.throw_std_exception");
fiu_disable("VecIndexImpl.BuildAll.throw_std_exception");
fiu_enable("VecIndexImpl.Add.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.Add.throw_knowhere_exception", 1, nullptr, 0);
s = index_->Add(nb, xb.data(), ids.data());
fiu_disable("VecIndexImpl.Add.throw_knowhere_exception");
fiu_enable("VecIndexImpl.Add.throw_std_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.Add.throw_std_exception", 1, nullptr, 0);
s = index_->Add(nb, xb.data(), ids.data());
fiu_disable("VecIndexImpl.Add.throw_std_exception");
fiu_enable("VecIndexImpl.Search.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.Search.throw_knowhere_exception", 1, nullptr, 0);
s = index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf);
fiu_disable("VecIndexImpl.Search.throw_knowhere_exception");
fiu_enable("VecIndexImpl.Search.throw_std_exception", 1, NULL, 0);
fiu_enable("VecIndexImpl.Search.throw_std_exception", 1, nullptr, 0);
s = index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf);
fiu_disable("VecIndexImpl.Search.throw_std_exception");
}
@ -229,17 +229,17 @@ TEST_P(KnowhereWrapperTest, SERIALIZE_TEST) {
{
std::string file_location = "/tmp/knowhere_gpu_file";
fiu_init(0);
fiu_enable("VecIndex.write_index.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("VecIndex.write_index.throw_knowhere_exception", 1, nullptr, 0);
auto s = write_index(index_, file_location);
ASSERT_FALSE(s.ok());
fiu_disable("VecIndex.write_index.throw_knowhere_exception");
fiu_enable("VecIndex.write_index.throw_std_exception", 1, NULL, 0);
fiu_enable("VecIndex.write_index.throw_std_exception", 1, nullptr, 0);
s = write_index(index_, file_location);
ASSERT_FALSE(s.ok());
fiu_disable("VecIndex.write_index.throw_std_exception");
fiu_enable("VecIndex.write_index.throw_no_space_exception", 1, NULL, 0);
fiu_enable("VecIndex.write_index.throw_no_space_exception", 1, nullptr, 0);
s = write_index(index_, file_location);
ASSERT_FALSE(s.ok());
fiu_disable("VecIndex.write_index.throw_no_space_exception");
@ -294,7 +294,7 @@ TEST_P(KnowhereWrapperTest, SERIALIZE_TEST) {
// conf.metric_type = knowhere::METRICTYPE::L2;
// fiu_init(0);
// fiu_enable("IVFPQConfAdapter.Match.empty_resset", 1, NULL, 0);
// fiu_enable("IVFPQConfAdapter.Match.empty_resset", 1, nullptr, 0);
// try {
// ivf_pq_conf->Match(conf);
// } catch (std::exception& e) {
@ -319,12 +319,12 @@ TEST(BFIndex, test_bf_index_fail) {
milvus::engine::Config config;
fiu_init(0);
fiu_enable("BFIndex.Build.throw_knowhere_exception", 1, NULL, 0);
fiu_enable("BFIndex.Build.throw_knowhere_exception", 1, nullptr, 0);
auto err_code = bf_ptr->Build(config);
ASSERT_EQ(err_code, milvus::KNOWHERE_UNEXPECTED_ERROR);
fiu_disable("BFIndex.Build.throw_knowhere_exception");
fiu_enable("BFIndex.Build.throw_std_exception", 1, NULL, 0);
fiu_enable("BFIndex.Build.throw_std_exception", 1, nullptr, 0);
err_code = bf_ptr->Build(config);
ASSERT_EQ(err_code, milvus::KNOWHERE_ERROR);
fiu_disable("BFIndex.Build.throw_std_exception");

View File

@ -46,7 +46,7 @@ struct QueryColumn {
struct TermQuery {
std::string field_name;
std::vector<std::string> field_value;
std::vector<uint8_t> field_value;
float boost;
};
using TermQueryPtr = std::shared_ptr<TermQuery>;

View File

@ -11,18 +11,17 @@
#include "scheduler/JobMgr.h"
#include <src/db/Utils.h>
#include <src/segment/SegmentReader.h>
#include "src/db/Utils.h"
#include "src/segment/SegmentReader.h"
#include <limits>
#include <utility>
#include "SchedInst.h"
#include "TaskCreator.h"
#include "optimizer/Optimizer.h"
#include "scheduler/Algorithm.h"
#include "scheduler/optimizer/Optimizer.h"
#include "scheduler/tasklabel/SpecResLabel.h"
#include "selector/Optimizer.h"
#include "task/Task.h"
namespace milvus {

View File

@ -16,14 +16,14 @@
#include "ResourceMgr.h"
#include "Scheduler.h"
#include "Utils.h"
#include "optimizer/BuildIndexPass.h"
#include "optimizer/FaissFlatPass.h"
#include "optimizer/FaissIVFFlatPass.h"
#include "optimizer/FaissIVFPQPass.h"
#include "optimizer/FaissIVFSQ8HPass.h"
#include "optimizer/FaissIVFSQ8Pass.h"
#include "optimizer/FallbackPass.h"
#include "optimizer/Optimizer.h"
#include "selector/BuildIndexPass.h"
#include "selector/FaissFlatPass.h"
#include "selector/FaissIVFFlatPass.h"
#include "selector/FaissIVFPQPass.h"
#include "selector/FaissIVFSQ8HPass.h"
#include "selector/FaissIVFSQ8Pass.h"
#include "selector/FallbackPass.h"
#include "selector/Optimizer.h"
#include <memory>
#include <mutex>

View File

@ -12,7 +12,7 @@
#include "scheduler/SchedInst.h"
#include "scheduler/Utils.h"
#include "scheduler/optimizer/BuildIndexPass.h"
#include "scheduler/selector/BuildIndexPass.h"
#include "scheduler/tasklabel/SpecResLabel.h"
#ifdef MILVUS_GPU_VERSION
namespace milvus {

View File

@ -23,7 +23,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -9,7 +9,7 @@
// 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.
#ifdef MILVUS_GPU_VERSION
#include "scheduler/optimizer/FaissFlatPass.h"
#include "scheduler/selector/FaissFlatPass.h"
#include "cache/GpuCacheMgr.h"
#include "config/Config.h"
#include "scheduler/SchedInst.h"

View File

@ -24,7 +24,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -9,7 +9,7 @@
// 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.
#ifdef MILVUS_GPU_VERSION
#include "scheduler/optimizer/FaissIVFFlatPass.h"
#include "scheduler/selector/FaissIVFFlatPass.h"
#include "cache/GpuCacheMgr.h"
#include "config/Config.h"
#include "scheduler/SchedInst.h"

View File

@ -24,7 +24,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -9,7 +9,7 @@
// 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.
#ifdef MILVUS_GPU_VERSION
#include "scheduler/optimizer/FaissIVFPQPass.h"
#include "scheduler/selector/FaissIVFPQPass.h"
#include "cache/GpuCacheMgr.h"
#include "config/Config.h"
#include "scheduler/SchedInst.h"

View File

@ -24,7 +24,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -10,7 +10,7 @@
// or implied. See the License for the specific language governing permissions and limitations under the License.
#ifdef MILVUS_GPU_VERSION
#include "scheduler/optimizer/FaissIVFSQ8HPass.h"
#include "scheduler/selector/FaissIVFSQ8HPass.h"
#include "cache/GpuCacheMgr.h"
#include "config/Config.h"
#include "scheduler/SchedInst.h"

View File

@ -24,7 +24,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -9,7 +9,7 @@
// 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.
#ifdef MILVUS_GPU_VERSION
#include "scheduler/optimizer/FaissIVFSQ8Pass.h"
#include "scheduler/selector/FaissIVFSQ8Pass.h"
#include "cache/GpuCacheMgr.h"
#include "config/Config.h"
#include "scheduler/SchedInst.h"

View File

@ -24,7 +24,7 @@
#include <vector>
#include "config/handler/GpuResourceConfigHandler.h"
#include "scheduler/optimizer/Pass.h"
#include "scheduler/selector/Pass.h"
namespace milvus {
namespace scheduler {

View File

@ -9,7 +9,7 @@
// 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 "scheduler/optimizer/FallbackPass.h"
#include "scheduler/selector/FallbackPass.h"
#include "scheduler/SchedInst.h"
#include "scheduler/tasklabel/SpecResLabel.h"

View File

@ -9,7 +9,7 @@
// 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 "scheduler/optimizer/Optimizer.h"
#include "scheduler/selector/Optimizer.h"
namespace milvus {
namespace scheduler {

View File

@ -306,9 +306,6 @@ XSearchTask::Execute() {
} else if (!vectors.binary_data_.empty()) {
s = index_engine_->Search(nq, vectors.binary_data_.data(), topk, extra_params, output_distance.data(),
output_ids.data(), hybrid);
} else if (!vectors.id_array_.empty()) {
s = index_engine_->Search(nq, vectors.id_array_, topk, extra_params, output_distance.data(),
output_ids.data(), hybrid);
}
fiu_do_on("XSearchTask.Execute.search_fail", s = Status(SERVER_UNEXPECTED_ERROR, ""));

View File

@ -28,9 +28,10 @@
#include "server/delivery/request/DropIndexRequest.h"
#include "server/delivery/request/DropPartitionRequest.h"
#include "server/delivery/request/FlushRequest.h"
#include "server/delivery/request/GetVectorByIDRequest.h"
#include "server/delivery/request/GetVectorIDsRequest.h"
#include "server/delivery/request/GetVectorsByIDRequest.h"
#include "server/delivery/request/HasCollectionRequest.h"
#include "server/delivery/request/HasPartitionRequest.h"
#include "server/delivery/request/InsertRequest.h"
#include "server/delivery/request/PreloadCollectionRequest.h"
#include "server/delivery/request/SearchByIDRequest.h"
@ -40,6 +41,7 @@
#include "server/delivery/request/ShowPartitionsRequest.h"
#include "server/delivery/hybrid_request/CreateHybridCollectionRequest.h"
#include "server/delivery/hybrid_request/DescribeHybridCollectionRequest.h"
#include "server/delivery/hybrid_request/HybridSearchRequest.h"
#include "server/delivery/hybrid_request/InsertEntityRequest.h"
@ -92,9 +94,9 @@ RequestHandler::Insert(const std::shared_ptr<Context>& context, const std::strin
}
Status
RequestHandler::GetVectorByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, engine::VectorsData& vectors) {
BaseRequestPtr request_ptr = GetVectorByIDRequest::Create(context, collection_name, ids, vectors);
RequestHandler::GetVectorsByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, std::vector<engine::VectorsData>& vectors) {
BaseRequestPtr request_ptr = GetVectorsByIDRequest::Create(context, collection_name, ids, vectors);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
@ -119,7 +121,7 @@ RequestHandler::ShowCollections(const std::shared_ptr<Context>& context, std::ve
Status
RequestHandler::ShowCollectionInfo(const std::shared_ptr<Context>& context, const std::string& collection_name,
CollectionInfo& collection_info) {
std::string& collection_info) {
BaseRequestPtr request_ptr = ShowCollectionInfoRequest::Create(context, collection_name, collection_info);
RequestScheduler::ExecRequest(request_ptr);
@ -140,10 +142,10 @@ RequestHandler::Search(const std::shared_ptr<Context>& context, const std::strin
Status
RequestHandler::SearchByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
int64_t vector_id, int64_t topk, const milvus::json& extra_params,
const std::vector<int64_t>& id_array, int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result) {
BaseRequestPtr request_ptr =
SearchByIDRequest::Create(context, collection_name, vector_id, topk, extra_params, partition_list, result);
SearchByIDRequest::Create(context, collection_name, id_array, topk, extra_params, partition_list, result);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
@ -218,6 +220,15 @@ RequestHandler::CreatePartition(const std::shared_ptr<Context>& context, const s
return request_ptr->status();
}
Status
RequestHandler::HasPartition(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& tag, bool& has_partition) {
BaseRequestPtr request_ptr = HasPartitionRequest::Create(context, collection_name, tag, has_partition);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
}
Status
RequestHandler::ShowPartitions(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::vector<PartitionParam>& partitions) {
@ -266,6 +277,15 @@ RequestHandler::CreateHybridCollection(const std::shared_ptr<Context>& context,
return request_ptr->status();
}
Status
RequestHandler::DescribeHybridCollection(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types) {
BaseRequestPtr request_ptr = DescribeHybridCollectionRequest::Create(context, collection_name, field_types);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
}
Status
RequestHandler::HasHybridCollection(const std::shared_ptr<Context>& context, std::string& collection_name,
bool& has_collection) {
@ -273,11 +293,11 @@ RequestHandler::HasHybridCollection(const std::shared_ptr<Context>& context, std
Status
RequestHandler::InsertEntity(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
const std::string& partition_tag, uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas) {
BaseRequestPtr request_ptr =
InsertEntityRequest::Create(context, collection_name, partition_tag, field_values, vector_datas);
BaseRequestPtr request_ptr = InsertEntityRequest::Create(context, collection_name, partition_tag, row_num,
field_names, attr_values, vector_datas);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();

View File

@ -48,8 +48,8 @@ class RequestHandler {
const std::string& partition_tag);
Status
GetVectorByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, engine::VectorsData& vectors);
GetVectorsByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, std::vector<engine::VectorsData>& vectors);
Status
GetVectorIDs(const std::shared_ptr<Context>& context, const std::string& collection_name,
@ -60,7 +60,7 @@ class RequestHandler {
Status
ShowCollectionInfo(const std::shared_ptr<Context>& context, const std::string& collection_name,
CollectionInfo& collection_info);
std::string& collection_info);
Status
Search(const std::shared_ptr<Context>& context, const std::string& collection_name,
@ -69,9 +69,9 @@ class RequestHandler {
TopKQueryResult& result);
Status
SearchByID(const std::shared_ptr<Context>& context, const std::string& collection_name, int64_t vector_id,
int64_t topk, const milvus::json& extra_params, const std::vector<std::string>& partition_list,
TopKQueryResult& result);
SearchByID(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::vector<int64_t>& id_array, int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result);
Status
DescribeCollection(const std::shared_ptr<Context>& context, const std::string& collection_name,
@ -100,6 +100,10 @@ class RequestHandler {
CreatePartition(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& tag);
Status
HasPartition(const std::shared_ptr<Context>& context, const std::string& collection_name, const std::string& tag,
bool& has_partition);
Status
ShowPartitions(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::vector<PartitionParam>& partitions);
@ -121,6 +125,10 @@ class RequestHandler {
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_extra_params);
Status
DescribeHybridCollection(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types);
Status
HasHybridCollection(const std::shared_ptr<Context>& context, std::string& collection_name, bool& has_collection);
@ -129,9 +137,8 @@ class RequestHandler {
Status
InsertEntity(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
const std::string& partition_tag, uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values, std::unordered_map<std::string, engine::VectorsData>& vector_datas);
Status
HybridSearch(const std::shared_ptr<Context>& context, context::HybridSearchContextPtr hybrid_search_context,

View File

@ -13,6 +13,7 @@
#include "db/Utils.h"
#include "server/DBWrapper.h"
#include "server/delivery/request/BaseRequest.h"
#include "server/web_impl/Constants.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
@ -78,9 +79,22 @@ CreateHybridCollectionRequest::OnExecute() {
fields_schema.fields_schema_[size].collection_id_ = collection_name_;
fields_schema.fields_schema_[size].field_name_ = vector_dimensions_[0].first;
fields_schema.fields_schema_[size].field_type_ = (int32_t)engine::meta::hybrid::DataType::VECTOR;
auto vector_param = field_params_[size].second;
fields_schema.fields_schema_[size].field_params_ = vector_param;
collection_info.dimension_ = vector_dimensions_[0].second;
// TODO(yukun): check dimension, metric_type, and assign engine_type
if (vector_param != "") {
auto json_param = nlohmann::json::parse(vector_param);
if (json_param.contains("metric_type")) {
int32_t metric_type = json_param["metric_type"];
collection_info.metric_type_ = metric_type;
}
if (json_param.contains("engine_type")) {
int32_t engine_type = json_param["engine_type"];
collection_info.engine_type_ = engine_type;
}
}
// step 3: create collection
status = DBWrapper::DB()->CreateHybridCollection(collection_info, fields_schema);

View File

@ -0,0 +1,71 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include "server/delivery/hybrid_request/DescribeHybridCollectionRequest.h"
#include "db/Utils.h"
#include "server/DBWrapper.h"
#include "server/delivery/request/BaseRequest.h"
#include "server/web_impl/Constants.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
#include <fiu-local.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace milvus {
namespace server {
DescribeHybridCollectionRequest::DescribeHybridCollectionRequest(
const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types)
: BaseRequest(context, BaseRequest::kDescribeHybridCollection),
collection_name_(collection_name),
field_types_(field_types) {
}
BaseRequestPtr
DescribeHybridCollectionRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types) {
return std::shared_ptr<BaseRequest>(new DescribeHybridCollectionRequest(context, collection_name, field_types));
}
Status
DescribeHybridCollectionRequest::OnExecute() {
std::string hdr = "CreateCollectionRequest(collection=" + collection_name_ + ")";
TimeRecorderAuto rc(hdr);
try {
engine::meta::CollectionSchema collection_schema;
engine::meta::hybrid::FieldsSchema fields_schema;
collection_schema.collection_id_ = collection_name_;
auto status = DBWrapper::DB()->DescribeHybridCollection(collection_schema, fields_schema);
if (!status.ok()) {
return status;
}
for (auto schema : fields_schema.fields_schema_) {
field_types_.insert(std::make_pair(schema.field_name_, (engine::meta::hybrid::DataType)schema.field_type_));
}
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}
return Status::OK();
}
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,45 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "server/delivery/request/BaseRequest.h"
namespace milvus {
namespace server {
class DescribeHybridCollectionRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types);
protected:
DescribeHybridCollectionRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types);
Status
OnExecute() override;
private:
const std::string collection_name_;
std::unordered_map<std::string, engine::meta::hybrid::DataType>& field_types_;
};
} // namespace server
} // namespace milvus

View File

@ -32,30 +32,32 @@ namespace server {
InsertEntityRequest::InsertEntityRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas)
: BaseRequest(context, BaseRequest::kInsertEntity),
collection_name_(collection_name),
partition_tag_(partition_tag),
field_values_(field_values),
row_num_(row_num),
field_names_(field_names),
attr_values_(attr_values),
vector_datas_(vector_datas) {
}
BaseRequestPtr
InsertEntityRequest::Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
const std::string& partition_tag, uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas) {
return std::shared_ptr<BaseRequest>(
new InsertEntityRequest(context, collection_name, partition_tag, field_values, vector_datas));
return std::shared_ptr<BaseRequest>(new InsertEntityRequest(context, collection_name, partition_tag, row_num,
field_names, attr_values, vector_datas));
}
Status
InsertEntityRequest::OnExecute() {
try {
fiu_do_on("InsertEntityRequest.OnExecute.throw_std_exception", throw std::exception());
std::string hdr = "InsertEntityRequest(table=" + collection_name_ + ", n=" + field_values_.begin()->first +
", partition_tag=" + partition_tag_ + ")";
std::string hdr = "InsertEntityRequest(table=" + collection_name_ + ", partition_tag=" + partition_tag_ + ")";
TimeRecorder rc(hdr);
// step 1: check arguments
@ -90,13 +92,13 @@ InsertEntityRequest::OnExecute() {
std::unordered_map<std::string, engine::meta::hybrid::DataType> field_types;
auto size = fields_schema.fields_schema_.size();
for (uint64_t i = 0; i < size; ++i) {
if (fields_schema.fields_schema_[i].field_type_ == (int32_t)engine::meta::hybrid::DataType::VECTOR) {
continue;
for (auto field_name : field_names_) {
for (uint64_t i = 0; i < size; ++i) {
if (fields_schema.fields_schema_[i].field_name_ == field_name) {
field_types.insert(std::make_pair(
field_name, (engine::meta::hybrid::DataType)fields_schema.fields_schema_[i].field_type_));
}
}
field_types.insert(
std::make_pair(fields_schema.fields_schema_[i].field_name_,
(engine::meta::hybrid::DataType)fields_schema.fields_schema_[i].field_type_));
}
// step 3: check table flag
@ -128,46 +130,18 @@ InsertEntityRequest::OnExecute() {
// step 4: some metric type doesn't support float vectors
// TODO(yukun): check dimension and metric_type
// for (uint64_t i = 0; i <entities_.vector_data_.size(); ++i) {
// if (!entities_.vector_data_[i].float_data_.empty()) { // insert float vectors
// if (engine::utils::IsBinaryMetricType(vector_fields.vector_fields_[i].metric_type_)) {
// return Status(SERVER_INVALID_ROWRECORD_ARRAY, "Table metric type doesn't support float
// vectors.");
// }
//
// // check prepared float data
// fiu_do_on("InsertRequest.OnExecute.invalid_dim", table_schema.dimension_ = -1);
// if (entities_.vector_data_[i].float_data_.size() / entities_.vector_data_[i].vector_count_ !=
// vector_fields.vector_fields_[i].dimension_) {
// return Status(SERVER_INVALID_VECTOR_DIMENSION,
// "The vector dimension must be equal to the table dimension.");
// }
// } else if (!entities_.vector_data_[i].binary_data_.empty()) { // insert binary vectors
// if (!engine::utils::IsBinaryMetricType(vector_fields.vector_fields_[i].metric_type_)) {
// return Status(SERVER_INVALID_ROWRECORD_ARRAY, "Table metric type doesn't support binary
// vectors.");
// }
//
// // check prepared binary data
// if (entities_.vector_data_[i].binary_data_.size() * 8 /
// entities_.vector_data_[i].vector_count_ != vector_fields.vector_fields_[i].dimension_) {
// return Status(SERVER_INVALID_VECTOR_DIMENSION,
// "The vector dimension must be equal to the table dimension.");
// }
// }
// }
// step 5: insert entities
auto vec_count = static_cast<uint64_t>(vector_datas_it->second.vector_count_);
engine::Entity entity;
entity.entity_count_ = vector_datas_it->second.vector_count_;
entity.entity_count_ = row_num_;
entity.attr_data_ = field_values_;
entity.attr_value_ = attr_values_;
entity.vector_data_.insert(std::make_pair(vector_datas_it->first, vector_datas_it->second));
rc.RecordSection("prepare vectors data");
status = DBWrapper::DB()->InsertEntities(collection_name_, partition_tag_, entity, field_types);
status = DBWrapper::DB()->InsertEntities(collection_name_, partition_tag_, field_names_, entity, field_types);
fiu_do_on("InsertRequest.OnExecute.insert_fail", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
return status;

View File

@ -25,13 +25,13 @@ class InsertEntityRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag, std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
const std::string& partition_tag, uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values, std::unordered_map<std::string, engine::VectorsData>& vector_datas);
protected:
InsertEntityRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
const std::string& partition_tag, uint64_t& row_num, std::vector<std::string>& field_names,
std::vector<uint8_t>& attr_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
Status
@ -40,7 +40,9 @@ class InsertEntityRequest : public BaseRequest {
private:
const std::string collection_name_;
const std::string partition_tag_;
std::unordered_map<std::string, std::vector<std::string>> field_values_;
uint64_t row_num_;
std::vector<std::string>& field_names_;
std::vector<uint8_t>& attr_values_;
std::unordered_map<std::string, engine::VectorsData>& vector_datas_;
};

View File

@ -49,6 +49,7 @@ RequestGroup(BaseRequest::RequestType type) {
{BaseRequest::kDropCollection, DDL_DML_REQUEST_GROUP},
{BaseRequest::kPreloadCollection, DQL_REQUEST_GROUP},
{BaseRequest::kCreateHybridCollection, DDL_DML_REQUEST_GROUP},
{BaseRequest::kDescribeHybridCollection, INFO_REQUEST_GROUP},
// partition operations
{BaseRequest::kCreatePartition, DDL_DML_REQUEST_GROUP},

View File

@ -103,24 +103,6 @@ struct PartitionParam {
}
};
struct SegmentStat {
std::string name_;
int64_t row_num_ = 0;
std::string index_name_;
int64_t data_size_ = 0;
};
struct PartitionStat {
std::string tag_;
int64_t total_row_num_ = 0;
std::vector<SegmentStat> segments_stat_;
};
struct CollectionInfo {
int64_t total_row_num_ = 0;
std::vector<PartitionStat> partitions_stat_;
};
class BaseRequest {
public:
enum RequestType {

View File

@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
#include "server/delivery/request/GetVectorByIDRequest.h"
#include "server/delivery/request/GetVectorsByIDRequest.h"
#include "server/DBWrapper.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
@ -27,9 +27,11 @@
namespace milvus {
namespace server {
GetVectorByIDRequest::GetVectorByIDRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::vector<int64_t>& ids,
engine::VectorsData& vectors)
constexpr uint64_t MAX_COUNT_RETURNED = 1000;
GetVectorsByIDRequest::GetVectorsByIDRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::vector<int64_t>& ids,
std::vector<engine::VectorsData>& vectors)
: BaseRequest(context, BaseRequest::kGetVectorByID),
collection_name_(collection_name),
ids_(ids),
@ -37,28 +39,33 @@ GetVectorByIDRequest::GetVectorByIDRequest(const std::shared_ptr<milvus::server:
}
BaseRequestPtr
GetVectorByIDRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::vector<int64_t>& ids,
engine::VectorsData& vectors) {
return std::shared_ptr<BaseRequest>(new GetVectorByIDRequest(context, collection_name, ids, vectors));
GetVectorsByIDRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::vector<int64_t>& ids,
std::vector<engine::VectorsData>& vectors) {
return std::shared_ptr<BaseRequest>(new GetVectorsByIDRequest(context, collection_name, ids, vectors));
}
Status
GetVectorByIDRequest::OnExecute() {
GetVectorsByIDRequest::OnExecute() {
try {
std::string hdr = "GetVectorByIDRequest(collection=" + collection_name_ + ")";
std::string hdr = "GetVectorsByIDRequest(collection=" + collection_name_ + ")";
TimeRecorderAuto rc(hdr);
// step 1: check arguments
if (ids_.empty()) {
return Status(SERVER_INVALID_ARGUMENT, "No vector id specified");
}
if (ids_.size() > MAX_COUNT_RETURNED) {
std::string msg = "Input id array size cannot exceed: " + std::to_string(MAX_COUNT_RETURNED);
return Status(SERVER_INVALID_ARGUMENT, msg);
}
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
return status;
}
if (ids_.empty()) {
return Status(SERVER_INVALID_ARGUMENT, "No vector id specified");
}
// only process root collection, ignore partition collection
engine::meta::CollectionSchema collection_schema;
collection_schema.collection_id_ = collection_name_;
@ -76,7 +83,7 @@ GetVectorByIDRequest::OnExecute() {
}
// step 2: get vector data, now only support get one id
return DBWrapper::DB()->GetVectorByID(collection_name_, ids_[0], vectors_);
return DBWrapper::DB()->GetVectorsByID(collection_name_, ids_, vectors_);
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}

View File

@ -26,15 +26,15 @@
namespace milvus {
namespace server {
class GetVectorByIDRequest : public BaseRequest {
class GetVectorsByIDRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, engine::VectorsData& vectors);
const std::vector<int64_t>& ids, std::vector<engine::VectorsData>& vectors);
protected:
GetVectorByIDRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, engine::VectorsData& vectors);
GetVectorsByIDRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::vector<int64_t>& ids, std::vector<engine::VectorsData>& vectors);
Status
OnExecute() override;
@ -42,7 +42,7 @@ class GetVectorByIDRequest : public BaseRequest {
private:
std::string collection_name_;
std::vector<int64_t> ids_;
engine::VectorsData& vectors_;
std::vector<engine::VectorsData>& vectors_;
};
} // namespace server

View File

@ -0,0 +1,74 @@
// 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 "server/delivery/request/HasPartitionRequest.h"
#include "server/DBWrapper.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
#include <fiu-local.h>
#include <memory>
#include <vector>
namespace milvus {
namespace server {
HasPartitionRequest::HasPartitionRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::string& tag,
bool& has_partition)
: BaseRequest(context, BaseRequest::kHasCollection),
collection_name_(collection_name),
partition_tag_(tag),
has_partition_(has_partition) {
}
BaseRequestPtr
HasPartitionRequest::Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& tag, bool& has_partition) {
return std::shared_ptr<BaseRequest>(new HasPartitionRequest(context, collection_name, tag, has_partition));
}
Status
HasPartitionRequest::OnExecute() {
try {
std::string hdr = "HasPartitionRequest(collection=" + collection_name_ + " tag=" + partition_tag_ + ")";
TimeRecorderAuto rc(hdr);
has_partition_ = false;
// step 1: check arguments
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
return status;
}
std::vector<engine::meta::CollectionSchema> schema_array;
status = DBWrapper::DB()->ShowPartitions(collection_name_, schema_array);
if (!status.ok()) {
return status;
}
for (auto& schema : schema_array) {
if (schema.partition_tag_ == partition_tag_) {
has_partition_ = true;
break;
}
}
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}
return Status::OK();
}
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,42 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include "server/delivery/request/BaseRequest.h"
#include <memory>
#include <string>
namespace milvus {
namespace server {
class HasPartitionRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& tag, bool& has_partition);
protected:
HasPartitionRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& tag, bool& has_partition);
Status
OnExecute() override;
private:
std::string collection_name_;
std::string partition_tag_;
bool& has_partition_;
};
} // namespace server
} // namespace milvus

View File

@ -34,12 +34,12 @@ namespace milvus {
namespace server {
SearchByIDRequest::SearchByIDRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, int64_t vector_id, int64_t topk,
const milvus::json& extra_params, const std::vector<std::string>& partition_list,
TopKQueryResult& result)
const std::string& collection_name, const std::vector<int64_t>& id_array,
int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result)
: BaseRequest(context, BaseRequest::kSearchByID),
collection_name_(collection_name),
vector_id_(vector_id),
id_array_(id_array),
topk_(topk),
extra_params_(extra_params),
partition_list_(partition_list),
@ -48,23 +48,26 @@ SearchByIDRequest::SearchByIDRequest(const std::shared_ptr<milvus::server::Conte
BaseRequestPtr
SearchByIDRequest::Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
int64_t vector_id, int64_t topk, const milvus::json& extra_params,
const std::vector<int64_t>& id_array, int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result) {
return std::shared_ptr<BaseRequest>(
new SearchByIDRequest(context, collection_name, vector_id, topk, extra_params, partition_list, result));
new SearchByIDRequest(context, collection_name, id_array, topk, extra_params, partition_list, result));
}
Status
SearchByIDRequest::OnExecute() {
try {
auto pre_query_ctx = context_->Child("Pre query");
milvus::server::ContextChild pre_tracer(context_, "Pre query");
std::string hdr = "SearchByIDRequest(collection=" + collection_name_ + ", id=" + std::to_string(vector_id_) +
", k=" + std::to_string(topk_) + ", extra_params=" + extra_params_.dump() + ")";
std::string hdr = "SearchByIDRequest(collection=" + collection_name_ + ", k=" + std::to_string(topk_) +
", extra_params=" + extra_params_.dump() + ")";
TimeRecorder rc(hdr);
// step 1: check empty id
// step 1: check empty id array
if (id_array_.empty()) {
return Status(SERVER_INVALID_ARGUMENT, "No vector id specified");
}
// step 2: check collection name
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
@ -140,10 +143,10 @@ SearchByIDRequest::OnExecute() {
ProfilerStart(fname.c_str());
#endif
pre_query_ctx->GetTraceContext()->GetSpan()->Finish();
pre_tracer.Finish();
status = DBWrapper::DB()->QueryByID(context_, collection_name_, partition_list_, (size_t)topk_, extra_params_,
vector_id_, result_ids, result_distances);
status = DBWrapper::DB()->QueryByIDs(context_, collection_name_, partition_list_, (size_t)topk_, extra_params_,
id_array_, result_ids, result_distances);
#ifdef MILVUS_ENABLE_PROFILING
ProfilerStop();
@ -158,14 +161,11 @@ SearchByIDRequest::OnExecute() {
return Status::OK(); // empty collection
}
auto post_query_ctx = context_->Child("Constructing result");
// step 9: construct result array
result_.row_num_ = 1;
result_.distance_list_ = result_distances;
result_.id_list_ = result_ids;
post_query_ctx->GetTraceContext()->GetSpan()->Finish();
milvus::server::ContextChild tracer(context_, "Constructing result");
result_.row_num_ = id_array_.size();
result_.distance_list_.swap(result_distances);
result_.id_list_.swap(result_ids);
rc.RecordSection("construct result and send");
rc.ElapseFromBegin("totally cost");

View File

@ -30,12 +30,12 @@ class SearchByIDRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
int64_t vector_id, int64_t topk, const milvus::json& extra_params,
const std::vector<int64_t>& id_array, int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result);
protected:
SearchByIDRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
int64_t vector_id, int64_t topk, const milvus::json& extra_params,
const std::vector<int64_t>& id_array, int64_t topk, const milvus::json& extra_params,
const std::vector<std::string>& partition_list, TopKQueryResult& result);
Status
@ -43,7 +43,7 @@ class SearchByIDRequest : public BaseRequest {
private:
const std::string collection_name_;
const int64_t vector_id_;
std::vector<int64_t> id_array_;
int64_t topk_;
milvus::json extra_params_;
const std::vector<std::string> partition_list_;

View File

@ -62,14 +62,14 @@ SearchRequest::OnPreExecute() {
// step 1: check collection name
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] %s", "search", 0, status.message().c_str());
return status;
}
// step 2: check search topk
status = ValidationUtil::ValidateSearchTopk(topk_);
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] %s", "search", 0, status.message().c_str());
return status;
}
@ -77,7 +77,7 @@ SearchRequest::OnPreExecute() {
status = ValidationUtil::ValidatePartitionTags(partition_list_);
fiu_do_on("SearchRequest.OnExecute.invalid_partition_tags", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] %s", "search", 0, status.message().c_str());
return status;
}
@ -92,7 +92,7 @@ SearchRequest::OnExecute() {
fiu_do_on("SearchRequest.OnExecute.throw_std_exception", throw std::exception());
std::string hdr = "SearchRequest execute(collection=" + collection_name_ +
", nq=" + std::to_string(vector_count) + ", k=" + std::to_string(topk_) + ")";
TimeRecorderAuto rc(LogOut("[%s][%d] %s", "search", 0, hdr.c_str()));
TimeRecorderAuto rc(LogOut("[%s][%ld] %s", "search", 0, hdr.c_str()));
// step 4: check collection existence
// only process root collection, ignore partition collection
@ -103,17 +103,17 @@ SearchRequest::OnExecute() {
status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
if (status.code() == DB_NOT_FOUND) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Collection %s not found: %s", "search", 0,
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Collection %s not found: %s", "search", 0,
collection_name_.c_str(), status.message().c_str());
return Status(SERVER_COLLECTION_NOT_EXIST, CollectionNotExistMsg(collection_name_));
} else {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Error occurred when describing collection %s: %s", "search", 0,
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Error occurred when describing collection %s: %s", "search", 0,
collection_name_.c_str(), status.message().c_str());
return status;
}
} else {
if (!collection_schema_.owner_collection_.empty()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] %s", "search", 0,
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] %s", "search", 0,
CollectionNotExistMsg(collection_name_).c_str());
return Status(SERVER_INVALID_COLLECTION_NAME, CollectionNotExistMsg(collection_name_));
}
@ -122,14 +122,14 @@ SearchRequest::OnExecute() {
// step 5: check search parameters
status = ValidationUtil::ValidateSearchParams(extra_params_, collection_schema_, topk_);
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Invalid search params: %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Invalid search params: %s", "search", 0, status.message().c_str());
return status;
}
// step 6: check vector data according to metric type
status = ValidationUtil::ValidateVectorData(vectors_data_, collection_schema_);
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Invalid vector data: %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Invalid vector data: %s", "search", 0, status.message().c_str());
return status;
}
@ -159,7 +159,7 @@ SearchRequest::OnExecute() {
#endif
fiu_do_on("SearchRequest.OnExecute.query_fail", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Query fail: %s", "search", 0, status.message().c_str());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Query fail: %s", "search", 0, status.message().c_str());
return status;
}
fiu_do_on("SearchRequest.OnExecute.empty_result_ids", result_ids.clear());
@ -174,7 +174,7 @@ SearchRequest::OnExecute() {
result_.distance_list_.swap(result_distances);
rc.RecordSection("construct result");
} catch (std::exception& ex) {
LOG_SERVER_ERROR_ << LogOut("[%s][%d] Encounter exception: %s", "search", 0, ex.what());
LOG_SERVER_ERROR_ << LogOut("[%s][%ld] Encounter exception: %s", "search", 0, ex.what());
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}

View File

@ -27,25 +27,8 @@
namespace milvus {
namespace server {
void
ConstructPartitionStat(const engine::PartitionStat& partition_stat, PartitionStat& req_partition_stat) {
int64_t row_count = 0;
req_partition_stat.tag_ = partition_stat.tag_;
for (auto& seg : partition_stat.segments_stat_) {
SegmentStat seg_stat;
seg_stat.name_ = seg.name_;
seg_stat.row_num_ = seg.row_count_;
seg_stat.index_name_ = seg.index_name_;
seg_stat.data_size_ = seg.data_size_;
req_partition_stat.segments_stat_.emplace_back(seg_stat);
row_count += seg.row_count_;
}
req_partition_stat.total_row_num_ = row_count;
}
ShowCollectionInfoRequest::ShowCollectionInfoRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name,
CollectionInfo& collection_info)
const std::string& collection_name, std::string& collection_info)
: BaseRequest(context, BaseRequest::kShowCollectionInfo),
collection_name_(collection_name),
collection_info_(collection_info) {
@ -53,7 +36,7 @@ ShowCollectionInfoRequest::ShowCollectionInfoRequest(const std::shared_ptr<milvu
BaseRequestPtr
ShowCollectionInfoRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, CollectionInfo& collection_info) {
const std::string& collection_name, std::string& collection_info) {
return std::shared_ptr<BaseRequest>(new ShowCollectionInfoRequest(context, collection_name, collection_info));
}
@ -86,24 +69,11 @@ ShowCollectionInfoRequest::OnExecute() {
}
// step 3: get partitions
engine::CollectionInfo collection_info;
status = DBWrapper::DB()->GetCollectionInfo(collection_name_, collection_info);
status = DBWrapper::DB()->GetCollectionInfo(collection_name_, collection_info_);
if (!status.ok()) {
return status;
}
// step 4: construct partitions info
int64_t total_row_count = 0;
collection_info_.partitions_stat_.reserve(collection_info.partitions_stat_.size());
for (auto& partition : collection_info.partitions_stat_) {
PartitionStat partition_stat;
ConstructPartitionStat(partition, partition_stat);
total_row_count += partition_stat.total_row_num_;
collection_info_.partitions_stat_.emplace_back(partition_stat);
}
collection_info_.total_row_num_ = total_row_count;
return Status::OK();
}

View File

@ -30,18 +30,18 @@ class ShowCollectionInfoRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
CollectionInfo& collection_info);
std::string& collection_info);
protected:
ShowCollectionInfoRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, CollectionInfo& collection_info);
const std::string& collection_name, std::string& collection_info);
Status
OnExecute() override;
private:
const std::string collection_name_;
CollectionInfo& collection_info_;
std::string& collection_info_;
};
} // namespace server

View File

@ -12,6 +12,7 @@
#include "server/grpc_impl/GrpcRequestHandler.h"
#include <fiu-local.h>
#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
@ -128,38 +129,6 @@ ConstructResults(const TopKQueryResult& result, ::milvus::grpc::TopKQueryResult*
result.distance_list_.size() * sizeof(float));
}
void
ConstructPartitionStat(const PartitionStat& partition_stat, ::milvus::grpc::PartitionStat* grpc_partition_stat) {
if (!grpc_partition_stat) {
return;
}
grpc_partition_stat->set_total_row_count(partition_stat.total_row_num_);
grpc_partition_stat->set_tag(partition_stat.tag_);
for (auto& seg_stat : partition_stat.segments_stat_) {
::milvus::grpc::SegmentStat* grpc_seg_stat = grpc_partition_stat->mutable_segments_stat()->Add();
grpc_seg_stat->set_row_count(seg_stat.row_num_);
grpc_seg_stat->set_segment_name(seg_stat.name_);
grpc_seg_stat->set_index_name(seg_stat.index_name_);
grpc_seg_stat->set_data_size(seg_stat.data_size_);
}
}
void
ConstructCollectionInfo(const CollectionInfo& collection_info, ::milvus::grpc::CollectionInfo* response) {
if (!response) {
return;
}
response->set_total_row_count(collection_info.total_row_num_);
for (auto& partition_stat : collection_info.partitions_stat_) {
::milvus::grpc::PartitionStat* grpc_partiton_stat = response->mutable_partitions_stat()->Add();
ConstructPartitionStat(partition_stat, grpc_partiton_stat);
}
}
} // namespace
namespace {
@ -406,24 +375,33 @@ GrpcRequestHandler::Insert(::grpc::ServerContext* context, const ::milvus::grpc:
}
::grpc::Status
GrpcRequestHandler::GetVectorByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorIdentity* request,
::milvus::grpc::VectorData* response) {
GrpcRequestHandler::GetVectorsByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorsIdentity* request,
::milvus::grpc::VectorsData* response) {
CHECK_NULLPTR_RETURN(request);
std::vector<int64_t> vector_ids = {request->id()};
engine::VectorsData vectors;
Status status =
request_handler_.GetVectorByID(GetContext(context), request->collection_name(), vector_ids, vectors);
if (!vectors.float_data_.empty()) {
response->mutable_vector_data()->mutable_float_data()->Resize(vectors.float_data_.size(), 0);
memcpy(response->mutable_vector_data()->mutable_float_data()->mutable_data(), vectors.float_data_.data(),
vectors.float_data_.size() * sizeof(float));
} else if (!vectors.binary_data_.empty()) {
response->mutable_vector_data()->mutable_binary_data()->resize(vectors.binary_data_.size());
memcpy(response->mutable_vector_data()->mutable_binary_data()->data(), vectors.binary_data_.data(),
vectors.binary_data_.size() * sizeof(uint8_t));
std::vector<int64_t> vector_ids;
vector_ids.reserve(request->id_array_size());
for (int i = 0; i < request->id_array_size(); i++) {
vector_ids.push_back(request->id_array(i));
}
std::vector<engine::VectorsData> vectors;
Status status =
request_handler_.GetVectorsByID(GetContext(context), request->collection_name(), vector_ids, vectors);
for (auto& vector : vectors) {
auto grpc_data = response->add_vectors_data();
if (!vector.float_data_.empty()) {
grpc_data->mutable_float_data()->Resize(vector.float_data_.size(), 0);
memcpy(grpc_data->mutable_float_data()->mutable_data(), vector.float_data_.data(),
vector.float_data_.size() * sizeof(float));
} else if (!vector.binary_data_.empty()) {
grpc_data->mutable_binary_data()->resize(vector.binary_data_.size());
memcpy(grpc_data->mutable_binary_data()->data(), vector.binary_data_.data(),
vector.binary_data_.size() * sizeof(uint8_t));
}
}
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
@ -460,9 +438,8 @@ GrpcRequestHandler::Search(::grpc::ServerContext* context, const ::milvus::grpc:
// step 2: partition tags
std::vector<std::string> partitions;
for (auto& partition : request->partition_tag_array()) {
partitions.emplace_back(partition);
}
std::copy(request->partition_tag_array().begin(), request->partition_tag_array().end(),
std::back_inserter(partitions));
// step 3: parse extra parameters
milvus::json json_params;
@ -498,11 +475,16 @@ GrpcRequestHandler::SearchByID(::grpc::ServerContext* context, const ::milvus::g
// step 1: partition tags
std::vector<std::string> partitions;
for (auto& partition : request->partition_tag_array()) {
partitions.emplace_back(partition);
std::copy(request->partition_tag_array().begin(), request->partition_tag_array().end(),
std::back_inserter(partitions));
// step 2: partition tags
std::vector<int64_t> id_array;
for (int i = 0; i < request->id_array_size(); i++) {
id_array.push_back(request->id_array(i));
}
// step 2: parse extra parameters
// step 3: parse extra parameters
milvus::json json_params;
for (int i = 0; i < request->extra_params_size(); i++) {
const ::milvus::grpc::KeyValuePair& extra = request->extra_params(i);
@ -511,12 +493,12 @@ GrpcRequestHandler::SearchByID(::grpc::ServerContext* context, const ::milvus::g
}
}
// step 3: search vectors
// step 4: search vectors
TopKQueryResult result;
Status status = request_handler_.SearchByID(GetContext(context), request->collection_name(), request->id(),
Status status = request_handler_.SearchByID(GetContext(context), request->collection_name(), id_array,
request->topk(), json_params, partitions, result);
// step 4: construct and return result
// step 5: construct and return result
ConstructResults(result, response);
SET_RESPONSE(response->mutable_status(), status, context);
@ -538,15 +520,12 @@ GrpcRequestHandler::SearchInFiles(::grpc::ServerContext* context, const ::milvus
// step 2: copy file id array
std::vector<std::string> file_ids;
for (auto& file_id : request->file_id_array()) {
file_ids.emplace_back(file_id);
}
std::copy(request->file_id_array().begin(), request->file_id_array().end(), std::back_inserter(file_ids));
// step 3: partition tags
std::vector<std::string> partitions;
for (auto& partition : search_request->partition_tag_array()) {
partitions.emplace_back(partition);
}
std::copy(search_request->partition_tag_array().begin(), search_request->partition_tag_array().end(),
std::back_inserter(partitions));
// step 4: parse extra parameters
milvus::json json_params;
@ -619,10 +598,10 @@ GrpcRequestHandler::ShowCollectionInfo(::grpc::ServerContext* context, const ::m
::milvus::grpc::CollectionInfo* response) {
CHECK_NULLPTR_RETURN(request);
CollectionInfo collection_info;
std::string collection_info;
Status status =
request_handler_.ShowCollectionInfo(GetContext(context), request->collection_name(), collection_info);
ConstructCollectionInfo(collection_info, response);
response->set_json_info(collection_info);
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
@ -709,6 +688,21 @@ GrpcRequestHandler::CreatePartition(::grpc::ServerContext* context, const ::milv
return ::grpc::Status::OK;
}
::grpc::Status
GrpcRequestHandler::HasPartition(::grpc::ServerContext* context, const ::milvus::grpc::PartitionParam* request,
::milvus::grpc::BoolReply* response) {
CHECK_NULLPTR_RETURN(request);
bool has_collection = false;
Status status =
request_handler_.HasPartition(GetContext(context), request->collection_name(), request->tag(), has_collection);
response->set_bool_reply(has_collection);
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
}
::grpc::Status
GrpcRequestHandler::ShowPartitions(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request,
::milvus::grpc::PartitionList* response) {
@ -800,23 +794,31 @@ GrpcRequestHandler::CreateHybridCollection(::grpc::ServerContext* context, const
return ::grpc::Status::OK;
}
::grpc::Status
GrpcRequestHandler::DescribeHybridCollection(::grpc::ServerContext* context,
const ::milvus::grpc::CollectionName* request,
::milvus::grpc::Mapping* response) {
CHECK_NULLPTR_RETURN(request);
}
::grpc::Status
GrpcRequestHandler::InsertEntity(::grpc::ServerContext* context, const ::milvus::grpc::HInsertParam* request,
::milvus::grpc::HEntityIDs* response) {
CHECK_NULLPTR_RETURN(request);
std::unordered_map<std::string, std::vector<std::string>> attr_values;
auto attr_size = request->entities().attr_records().size();
std::vector<uint8_t> attr_values(attr_size, 0);
std::unordered_map<std::string, engine::VectorsData> vector_datas;
auto attr_size = request->entities().attr_records_size();
for (uint64_t i = 0; i < attr_size; ++i) {
std::vector<std::string> values;
auto record_size = request->entities().attr_records(i).value_size();
values.resize(record_size);
for (uint64_t j = 0; j < record_size; ++j) {
values[j] = request->entities().attr_records(i).value(j);
}
attr_values.insert(std::make_pair(request->entities().field_names(i), values));
memcpy(attr_values.data(), request->entities().attr_records().data(), attr_size);
uint64_t row_num = request->entities().row_num();
std::vector<std::string> field_names;
auto field_size = request->entities().field_names_size();
field_names.resize(field_size - 1);
for (uint64_t i = 0; i < field_size - 1; ++i) {
field_names[i] = request->entities().field_names(i);
}
auto vector_size = request->entities().result_values_size();
@ -824,13 +826,13 @@ GrpcRequestHandler::InsertEntity(::grpc::ServerContext* context, const ::milvus:
engine::VectorsData vectors;
CopyRowRecords(request->entities().result_values(i).vector_value().value(), request->entity_id_array(),
vectors);
vector_datas.insert(std::make_pair(request->entities().field_names(attr_size + i), vectors));
vector_datas.insert(std::make_pair(request->entities().field_names(field_size - 1), vectors));
}
std::string collection_name = request->collection_name();
std::string partition_tag = request->partition_tag();
Status status =
request_handler_.InsertEntity(GetContext(context), collection_name, partition_tag, attr_values, vector_datas);
Status status = request_handler_.InsertEntity(GetContext(context), collection_name, partition_tag, row_num,
field_names, attr_values, vector_datas);
response->mutable_entity_id_array()->Resize(static_cast<int>(vector_datas.begin()->second.id_array_.size()), 0);
memcpy(response->mutable_entity_id_array()->mutable_data(), vector_datas.begin()->second.id_array_.data(),
@ -841,14 +843,12 @@ GrpcRequestHandler::InsertEntity(::grpc::ServerContext* context, const ::milvus:
}
void
DeSerialization(const ::milvus::grpc::GeneralQuery& general_query, query::BooleanQueryPtr boolean_clause) {
DeSerialization(const ::milvus::grpc::GeneralQuery& general_query, query::BooleanQueryPtr& boolean_clause) {
if (general_query.has_boolean_query()) {
// boolean_clause->SetOccur((query::Occur)general_query.boolean_query().occur());
boolean_clause->SetOccur((query::Occur)general_query.boolean_query().occur());
for (uint64_t i = 0; i < general_query.boolean_query().general_query_size(); ++i) {
if (general_query.boolean_query().general_query(i).has_boolean_query()) {
query::BooleanQueryPtr query =
std::make_shared<query::BooleanQuery>((query::Occur)(general_query.boolean_query().occur()));
query::BooleanQueryPtr query = std::make_shared<query::BooleanQuery>();
DeSerialization(general_query.boolean_query().general_query(i), query);
boolean_clause->AddBooleanQuery(query);
} else {
@ -858,10 +858,9 @@ DeSerialization(const ::milvus::grpc::GeneralQuery& general_query, query::Boolea
query::TermQueryPtr term_query = std::make_shared<query::TermQuery>();
term_query->field_name = query.term_query().field_name();
term_query->boost = query.term_query().boost();
term_query->field_value.resize(query.term_query().values_size());
for (uint64_t j = 0; j < query.term_query().values_size(); ++j) {
term_query->field_value[j] = query.term_query().values(j);
}
auto size = query.term_query().values().size();
term_query->field_value.resize(size);
memcpy(term_query->field_value.data(), query.term_query().values().data(), size);
leaf_query->term_query = term_query;
boolean_clause->AddLeafQuery(leaf_query);
}
@ -919,7 +918,6 @@ GrpcRequestHandler::HybridSearch(::grpc::ServerContext* context, const ::milvus:
DeSerialization(request->general_query(), boolean_query);
query::GeneralQueryPtr general_query = std::make_shared<query::GeneralQuery>();
general_query->bin = std::make_shared<query::BinaryQuery>();
query::GenBinaryQuery(boolean_query, general_query->bin);
Status status;

View File

@ -180,6 +180,17 @@ class GrpcRequestHandler final : public ::milvus::grpc::MilvusService::Service,
::grpc::Status
CreatePartition(::grpc::ServerContext* context, const ::milvus::grpc::PartitionParam* request,
::milvus::grpc::Status* response) override;
// *
// @brief This method is used to test partition existence.
//
// @param PartitionParam, target partition.
//
// @return BoolReply
::grpc::Status
HasPartition(::grpc::ServerContext* context, const ::milvus::grpc::PartitionParam* request,
::milvus::grpc::BoolReply* response);
// *
// @brief This method is used to show partition information
//
@ -208,14 +219,15 @@ class GrpcRequestHandler final : public ::milvus::grpc::MilvusService::Service,
Insert(::grpc::ServerContext* context, const ::milvus::grpc::InsertParam* request,
::milvus::grpc::VectorIds* response) override;
// *
// @brief This method is used to get vector data by id.
// @brief This method is used to get vectors data by id array.
//
// @param VectorIdentity, target vector id.
// @param VectorsIdentity, target vector id array.
//
// @return VectorData
// @return VectorsData
::grpc::Status
GetVectorByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorIdentity* request,
::milvus::grpc::VectorData* response);
GetVectorsByID(::grpc::ServerContext* context, const ::milvus::grpc::VectorsIdentity* request,
::milvus::grpc::VectorsData* response);
// *
// @brief This method is used to get vector ids from a segment
//
@ -320,10 +332,9 @@ class GrpcRequestHandler final : public ::milvus::grpc::MilvusService::Service,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::Status* response) override;
//
// ::grpc::Status
// DescribeCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::Mapping* response) override;
::grpc::Status
DescribeHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request,
::milvus::grpc::Mapping* response) override;
//
// ::grpc::Status
// CountCollection(::grpc::ServerContext* context,

View File

@ -11,19 +11,18 @@
#pragma once
#include <string>
#include <iostream>
#include <string>
#include <oatpp/web/server/api/ApiController.hpp>
#include <oatpp/parser/json/mapping/ObjectMapper.hpp>
#include <oatpp/core/macro/codegen.hpp>
#include <oatpp/core/macro/component.hpp>
#include <oatpp/parser/json/mapping/ObjectMapper.hpp>
#include <oatpp/web/server/api/ApiController.hpp>
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "server/web_impl/Constants.h"
#include "server/web_impl/dto/CmdDto.hpp"
#include "server/web_impl/dto/ConfigDto.hpp"
#include "server/web_impl/dto/IndexDto.hpp"
#include "server/web_impl/dto/PartitionDto.hpp"
@ -38,11 +37,12 @@ namespace web {
class WebController : public oatpp::web::server::api::ApiController {
public:
WebController(const std::shared_ptr<ObjectMapper>& objectMapper)
: oatpp::web::server::api::ApiController(objectMapper) {}
: oatpp::web::server::api::ApiController(objectMapper) {
}
public:
static std::shared_ptr<WebController> createShared(
OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper)) {
static std::shared_ptr<WebController>
createShared(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper)) {
return std::make_shared<WebController>(objectMapper);
}
@ -85,8 +85,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
@ -116,8 +116,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
@ -140,8 +140,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
@ -173,8 +173,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -198,8 +198,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
}
@ -230,8 +230,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
}
@ -244,7 +244,6 @@ class WebController : public oatpp::web::server::api::ApiController {
WebRequestHandler handler = WebRequestHandler();
String result;
auto status_dto = handler.ShowTables(query_params, result);
std::shared_ptr<OutgoingResponse> response;
@ -256,8 +255,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -271,8 +270,8 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(GetTable)
ENDPOINT("GET", "/collections/{collection_name}", GetTable,
PATH(String, collection_name), QUERIES(const QueryParams&, query_params)) {
ENDPOINT("GET", "/collections/{collection_name}", GetTable, PATH(String, collection_name),
QUERIES(const QueryParams&, query_params)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "GET \'/collections/" + collection_name->std_str() + "\'");
tr.RecordSection("Received request.");
@ -293,8 +292,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -321,8 +320,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -336,8 +335,8 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(CreateIndex)
ENDPOINT("POST", "/collections/{collection_name}/indexes", CreateIndex,
PATH(String, collection_name), BODY_STRING(String, body)) {
ENDPOINT("POST", "/collections/{collection_name}/indexes", CreateIndex, PATH(String, collection_name),
BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/tables/" + collection_name->std_str() + "/indexes\'");
tr.RecordSection("Received request.");
@ -356,8 +355,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -366,7 +365,8 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(GetIndex)
ENDPOINT("GET", "/collections/{collection_name}/indexes", GetIndex, PATH(String, collection_name)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "GET \'/collections/" + collection_name->std_str() + "/indexes\'");
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "GET \'/collections/" + collection_name->std_str() +
"/indexes\'");
tr.RecordSection("Received request.");
auto handler = WebRequestHandler();
@ -386,8 +386,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -396,7 +396,8 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(DropIndex)
ENDPOINT("DELETE", "/collections/{collection_name}/indexes", DropIndex, PATH(String, collection_name)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "DELETE \'/collections/" + collection_name->std_str() + "/indexes\'");
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "DELETE \'/collections/" + collection_name->std_str() +
"/indexes\'");
tr.RecordSection("Received request.");
auto handler = WebRequestHandler();
@ -414,8 +415,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost";
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
@ -429,9 +430,10 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(CreatePartition)
ENDPOINT("POST", "/collections/{collection_name}/partitions",
CreatePartition, PATH(String, collection_name), BODY_DTO(PartitionRequestDto::ObjectWrapper, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/collections/" + collection_name->std_str() + "/partitions\'");
ENDPOINT("POST", "/collections/{collection_name}/partitions", CreatePartition, PATH(String, collection_name),
BODY_DTO(PartitionRequestDto::ObjectWrapper, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/collections/" + collection_name->std_str() +
"/partitions\'");
tr.RecordSection("Received request.");
auto handler = WebRequestHandler();
@ -449,17 +451,18 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(ShowPartitions)
ENDPOINT("GET", "/collections/{collection_name}/partitions", ShowPartitions,
PATH(String, collection_name), QUERIES(const QueryParams&, query_params)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "GET \'/collections/" + collection_name->std_str() + "/partitions\'");
ENDPOINT("GET", "/collections/{collection_name}/partitions", ShowPartitions, PATH(String, collection_name),
QUERIES(const QueryParams&, query_params)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "GET \'/collections/" + collection_name->std_str() +
"/partitions\'");
tr.RecordSection("Received request.");
auto offset = query_params.get("offset");
@ -477,21 +480,22 @@ class WebController : public oatpp::web::server::api::ApiController {
case StatusCode::COLLECTION_NOT_EXISTS:
response = createDtoResponse(Status::CODE_404, status_dto);
break;
default:response = createDtoResponse(Status::CODE_400, status_dto);
default:
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(DropPartition)
ENDPOINT("DELETE", "/collections/{collection_name}/partitions", DropPartition,
PATH(String, collection_name), BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) +
"DELETE \'/collections/" + collection_name->std_str() + "/partitions\'");
ENDPOINT("DELETE", "/collections/{collection_name}/partitions", DropPartition, PATH(String, collection_name),
BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "DELETE \'/collections/" + collection_name->std_str() +
"/partitions\'");
tr.RecordSection("Received request.");
auto handler = WebRequestHandler();
@ -509,16 +513,16 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(ShowSegments)
ENDPOINT("GET", "/collections/{collection_name}/segments", ShowSegments,
PATH(String, collection_name), QUERIES(const QueryParams&, query_params)) {
ENDPOINT("GET", "/collections/{collection_name}/segments", ShowSegments, PATH(String, collection_name),
QUERIES(const QueryParams&, query_params)) {
auto offset = query_params.get("offset");
auto page_size = query_params.get("page_size");
@ -542,7 +546,8 @@ class WebController : public oatpp::web::server::api::ApiController {
* GetSegmentVector
*/
ENDPOINT("GET", "/collections/{collection_name}/segments/{segment_name}/{info}", GetSegmentInfo,
PATH(String, collection_name), PATH(String, segment_name), PATH(String, info), QUERIES(const QueryParams&, query_params)) {
PATH(String, collection_name), PATH(String, segment_name), PATH(String, info),
QUERIES(const QueryParams&, query_params)) {
auto offset = query_params.get("offset");
auto page_size = query_params.get("page_size");
@ -571,8 +576,8 @@ class WebController : public oatpp::web::server::api::ApiController {
*
* GetVectorByID ?id=
*/
ENDPOINT("GET", "/collections/{collection_name}/vectors", GetVectors,
PATH(String, collection_name), QUERIES(const QueryParams&, query_params)) {
ENDPOINT("GET", "/collections/{collection_name}/vectors", GetVectors, PATH(String, collection_name),
QUERIES(const QueryParams&, query_params)) {
auto handler = WebRequestHandler();
String response;
auto status_dto = handler.GetVector(collection_name, query_params, response);
@ -589,9 +594,10 @@ class WebController : public oatpp::web::server::api::ApiController {
ADD_CORS(Insert)
ENDPOINT("POST", "/collections/{collection_name}/vectors", Insert,
PATH(String, collection_name), BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/collections/" + collection_name->std_str() + "/vectors\'");
ENDPOINT("POST", "/collections/{collection_name}/vectors", Insert, PATH(String, collection_name),
BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/collections/" + collection_name->std_str() +
"/vectors\'");
tr.RecordSection("Received request.");
auto ids_dto = VectorIdsDto::createShared();
@ -610,17 +616,48 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(InsertEntity)
ENDPOINT("POST", "/hybrid_collections/{collection_name}/entities", InsertEntity, PATH(String, collection_name),
BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/hybrid_collections/" + collection_name->std_str() +
"/entities\'");
tr.RecordSection("Received request.");
auto ids_dto = VectorIdsDto::createShared();
WebRequestHandler handler = WebRequestHandler();
std::shared_ptr<OutgoingResponse> response;
auto status_dto = handler.InsertEntity(collection_name, body, ids_dto);
switch (status_dto->code->getValue()) {
case StatusCode::SUCCESS:
response = createDtoResponse(Status::CODE_201, ids_dto);
break;
case StatusCode::COLLECTION_NOT_EXISTS:
response = createDtoResponse(Status::CODE_404, status_dto);
break;
default:
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(VectorsOp)
ENDPOINT("PUT", "/collections/{collection_name}/vectors", VectorsOp,
PATH(String, collection_name), BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "PUT \'/collections/" + collection_name->std_str() + "/vectors\'");
ENDPOINT("PUT", "/collections/{collection_name}/vectors", VectorsOp, PATH(String, collection_name),
BODY_STRING(String, body)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "PUT \'/collections/" + collection_name->std_str() +
"/vectors\'");
tr.RecordSection("Received request.");
WebRequestHandler handler = WebRequestHandler();
@ -639,8 +676,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
@ -669,8 +706,8 @@ class WebController : public oatpp::web::server::api::ApiController {
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
@ -695,19 +732,41 @@ class WebController : public oatpp::web::server::api::ApiController {
default:
response = createDtoResponse(Status::CODE_400, status_dto);
}
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue())
+ ", reason = " + status_dto->message->std_str() + ". Total cost");
tr.ElapseFromBegin("Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost");
return response;
}
ADD_CORS(CreateHybridCollection)
ENDPOINT("POST", "/hybrid_collections", CreateHybridCollection, BODY_STRING(String, body_str)) {
TimeRecorder tr(std::string(WEB_LOG_PREFIX) + "POST \'/hybrid_collections\'");
tr.RecordSection("Received request.");
WebRequestHandler handler = WebRequestHandler();
std::shared_ptr<OutgoingResponse> response;
auto status_dto = handler.CreateHybridCollection(body_str);
switch (status_dto->code->getValue()) {
case StatusCode::SUCCESS:
response = createDtoResponse(Status::CODE_201, status_dto);
break;
default:
response = createDtoResponse(Status::CODE_400, status_dto);
}
std::string ttr = "Done. Status: code = " + std::to_string(status_dto->code->getValue()) +
", reason = " + status_dto->message->std_str() + ". Total cost";
tr.ElapseFromBegin(ttr);
return response;
}
/**
* Finish ENDPOINTs generation ('ApiController' codegen)
*/
#include OATPP_CODEGEN_END(ApiController)
};
} // namespace web
} // namespace server
} // namespace milvus
} // namespace web
} // namespace server
} // namespace milvus

View File

@ -15,6 +15,7 @@
#include <cmath>
#include <ctime>
#include <string>
#include <unordered_map>
#include <vector>
#include "config/Config.h"
@ -83,32 +84,6 @@ WebRequestHandler::AddStatusToJson(nlohmann::json& json, int64_t code, const std
json["message"] = msg;
}
Status
WebRequestHandler::ParseSegmentStat(const milvus::server::SegmentStat& seg_stat, nlohmann::json& json) {
json["segment_name"] = seg_stat.name_;
json["index"] = seg_stat.index_name_;
json["count"] = seg_stat.row_num_;
json["size"] = seg_stat.data_size_;
return Status::OK();
}
Status
WebRequestHandler::ParsePartitionStat(const milvus::server::PartitionStat& par_stat, nlohmann::json& json) {
json["partition_tag"] = par_stat.tag_;
json["count"] = par_stat.total_row_num_;
std::vector<nlohmann::json> seg_stat_json;
for (auto& seg : par_stat.segments_stat_) {
nlohmann::json seg_json;
ParseSegmentStat(seg, seg_json);
seg_stat_json.push_back(seg_json);
}
json["segments_stat"] = seg_stat_json;
return Status::OK();
}
Status
WebRequestHandler::IsBinaryTable(const std::string& collection_name, bool& bin) {
CollectionSchema schema;
@ -188,19 +163,14 @@ WebRequestHandler::GetTableMetaInfo(const std::string& collection_name, nlohmann
Status
WebRequestHandler::GetTableStat(const std::string& collection_name, nlohmann::json& json_out) {
struct CollectionInfo collection_info;
std::string collection_info;
auto status = request_handler_.ShowCollectionInfo(context_ptr_, collection_name, collection_info);
if (status.ok()) {
json_out["count"] = collection_info.total_row_num_;
std::vector<nlohmann::json> par_stat_json;
for (auto& par : collection_info.partitions_stat_) {
nlohmann::json par_json;
ParsePartitionStat(par, par_json);
par_stat_json.push_back(par_json);
try {
json_out = nlohmann::json::parse(collection_info);
} catch (std::exception& e) {
}
json_out["partitions_stat"] = par_stat_json;
}
return status;
@ -515,6 +485,251 @@ WebRequestHandler::Search(const std::string& collection_name, const nlohmann::js
return Status::OK();
}
Status
WebRequestHandler::ProcessLeafQueryJson(const nlohmann::json& json, milvus::query::BooleanQueryPtr& query) {
if (json.contains("term")) {
auto leaf_query = std::make_shared<query::LeafQuery>();
auto term_json = json["term"];
std::string field_name = term_json["field_name"];
auto term_value_json = term_json["values"];
if (!term_value_json.is_array()) {
std::string msg = "Term json string is not an array";
return Status{BODY_PARSE_FAIL, msg};
}
auto term_size = term_value_json.size();
auto term_query = std::make_shared<query::TermQuery>();
term_query->field_name = field_name;
term_query->field_value.resize(term_size * sizeof(int64_t));
switch (field_type_.at(field_name)) {
case engine::meta::hybrid::DataType::INT8:
case engine::meta::hybrid::DataType::INT16:
case engine::meta::hybrid::DataType::INT32:
case engine::meta::hybrid::DataType::INT64: {
std::vector<int64_t> term_value(term_size, 0);
for (uint64_t i = 0; i < term_size; ++i) {
term_value[i] = term_value_json[i].get<int64_t>();
}
memcpy(term_query->field_value.data(), term_value.data(), term_size * sizeof(int64_t));
break;
}
case engine::meta::hybrid::DataType::FLOAT:
case engine::meta::hybrid::DataType::DOUBLE: {
std::vector<double> term_value(term_size, 0);
for (uint64_t i = 0; i < term_size; ++i) {
term_value[i] = term_value_json[i].get<double>();
}
memcpy(term_query->field_value.data(), term_value.data(), term_size * sizeof(double));
break;
}
}
leaf_query->term_query = term_query;
query->AddLeafQuery(leaf_query);
} else if (json.contains("range")) {
auto leaf_query = std::make_shared<query::LeafQuery>();
auto range_query = std::make_shared<query::RangeQuery>();
auto range_json = json["range"];
std::string field_name = range_json["field_name"];
range_query->field_name = field_name;
auto range_value_json = range_json["values"];
if (range_value_json.contains("lt")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::LT;
compare_expr.operand = range_value_json["lt"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
if (range_value_json.contains("lte")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::LTE;
compare_expr.operand = range_value_json["lte"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
if (range_value_json.contains("eq")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::EQ;
compare_expr.operand = range_value_json["eq"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
if (range_value_json.contains("ne")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::NE;
compare_expr.operand = range_value_json["ne"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
if (range_value_json.contains("gt")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::GT;
compare_expr.operand = range_value_json["gt"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
if (range_value_json.contains("gte")) {
query::CompareExpr compare_expr;
compare_expr.compare_operator = query::CompareOperator::GTE;
compare_expr.operand = range_value_json["gte"].get<std::string>();
range_query->compare_expr.emplace_back(compare_expr);
}
leaf_query->range_query = range_query;
query->AddLeafQuery(leaf_query);
} else if (json.contains("vector")) {
auto leaf_query = std::make_shared<query::LeafQuery>();
auto vector_query = std::make_shared<query::VectorQuery>();
auto vector_json = json["vector"];
std::string field_name = vector_json["field_name"];
vector_query->field_name = field_name;
engine::VectorsData vectors;
// TODO(yukun): process binary vector
CopyRecordsFromJson(vector_json["values"], vectors, false);
vector_query->query_vector.float_data = vectors.float_data_;
vector_query->query_vector.binary_data = vectors.binary_data_;
vector_query->topk = vector_json["topk"].get<int64_t>();
vector_query->extra_params = vector_json["extra_params"];
leaf_query->vector_query = vector_query;
query->AddLeafQuery(leaf_query);
}
return Status::OK();
}
Status
WebRequestHandler::ProcessBoolQueryJson(const nlohmann::json& query_json, query::BooleanQueryPtr& boolean_query) {
if (query_json.contains("must")) {
boolean_query->SetOccur(query::Occur::MUST);
auto must_json = query_json["must"];
if (!must_json.is_array()) {
std::string msg = "Must json string is not an array";
return Status{BODY_PARSE_FAIL, msg};
}
for (auto& json : must_json) {
auto must_query = std::make_shared<query::BooleanQuery>();
if (json.contains("must") || json.contains("should") || json.contains("must_not")) {
ProcessBoolQueryJson(json, must_query);
boolean_query->AddBooleanQuery(must_query);
} else {
ProcessLeafQueryJson(json, boolean_query);
}
}
return Status::OK();
} else if (query_json.contains("should")) {
boolean_query->SetOccur(query::Occur::SHOULD);
auto should_json = query_json["should"];
if (!should_json.is_array()) {
std::string msg = "Should json string is not an array";
return Status{BODY_PARSE_FAIL, msg};
}
for (auto& json : should_json) {
if (json.contains("must") || json.contains("should") || json.contains("must_not")) {
auto should_query = std::make_shared<query::BooleanQuery>();
ProcessBoolQueryJson(json, should_query);
boolean_query->AddBooleanQuery(should_query);
} else {
ProcessLeafQueryJson(json, boolean_query);
}
}
return Status::OK();
} else if (query_json.contains("must_not")) {
boolean_query->SetOccur(query::Occur::MUST_NOT);
auto should_json = query_json["must_not"];
if (!should_json.is_array()) {
std::string msg = "Must_not json string is not an array";
return Status{BODY_PARSE_FAIL, msg};
}
for (auto& json : should_json) {
if (json.contains("must") || json.contains("should") || json.contains("must_not")) {
auto must_not_query = std::make_shared<query::BooleanQuery>();
ProcessBoolQueryJson(json, must_not_query);
boolean_query->AddBooleanQuery(must_not_query);
} else {
ProcessLeafQueryJson(json, boolean_query);
}
}
return Status::OK();
} else {
std::string msg = "Must json string doesnot include right query";
return Status{BODY_PARSE_FAIL, msg};
}
}
Status
WebRequestHandler::HybridSearch(const std::string& collection_name, const nlohmann::json& json,
std::string& result_str) {
Status status;
status = request_handler_.DescribeHybridCollection(context_ptr_, collection_name, field_type_);
if (!status.ok()) {
return Status{UNEXPECTED_ERROR, "DescribeHybridCollection failed"};
}
std::vector<std::string> partition_tags;
if (json.contains("partition_tags")) {
auto tags = json["partition_tags"];
if (!tags.is_null() && !tags.is_array()) {
return Status(BODY_PARSE_FAIL, "Field \"partition_tags\" must be a array");
}
for (auto& tag : tags) {
partition_tags.emplace_back(tag.get<std::string>());
}
}
if (json.contains("bool")) {
auto boolean_query_json = json["bool"];
query::BooleanQueryPtr boolean_query = std::make_shared<query::BooleanQuery>();
status = ProcessBoolQueryJson(boolean_query_json, boolean_query);
if (!status.ok()) {
return status;
}
query::GeneralQueryPtr general_query = std::make_shared<query::GeneralQuery>();
query::GenBinaryQuery(boolean_query, general_query->bin);
context::HybridSearchContextPtr hybrid_search_context = std::make_shared<context::HybridSearchContext>();
TopKQueryResult result;
status = request_handler_.HybridSearch(context_ptr_, hybrid_search_context, collection_name, partition_tags,
general_query, result);
if (!status.ok()) {
return status;
}
nlohmann::json result_json;
result_json["num"] = result.row_num_;
if (result.row_num_ == 0) {
result_json["result"] = std::vector<int64_t>();
result_str = result_json.dump();
return Status::OK();
}
auto step = result.id_list_.size() / result.row_num_;
nlohmann::json search_result_json;
for (size_t i = 0; i < result.row_num_; i++) {
nlohmann::json raw_result_json;
for (size_t j = 0; j < step; j++) {
nlohmann::json one_result_json;
one_result_json["id"] = std::to_string(result.id_list_.at(i * step + j));
one_result_json["distance"] = std::to_string(result.distance_list_.at(i * step + j));
raw_result_json.emplace_back(one_result_json);
}
search_result_json.emplace_back(raw_result_json);
}
result_json["result"] = search_result_json;
result_str = result_json.dump();
}
return Status::OK();
}
Status
WebRequestHandler::DeleteByIDs(const std::string& collection_name, const nlohmann::json& json,
std::string& result_str) {
@ -548,18 +763,13 @@ Status
WebRequestHandler::GetVectorsByIDs(const std::string& collection_name, const std::vector<int64_t>& ids,
nlohmann::json& json_out) {
std::vector<engine::VectorsData> vector_batch;
for (size_t i = 0; i < ids.size(); i++) {
auto vec_ids = std::vector<int64_t>(ids.begin() + i, ids.begin() + i + 1);
engine::VectorsData vectors_data;
auto status = request_handler_.GetVectorByID(context_ptr_, collection_name, vec_ids, vectors_data);
if (!status.ok()) {
return status;
}
vector_batch.push_back(vectors_data);
auto status = request_handler_.GetVectorsByID(context_ptr_, collection_name, ids, vector_batch);
if (!status.ok()) {
return status;
}
bool bin;
auto status = IsBinaryTable(collection_name, bin);
status = IsBinaryTable(collection_name, bin);
if (!status.ok()) {
return status;
}
@ -878,6 +1088,50 @@ WebRequestHandler::CreateTable(const TableRequestDto::ObjectWrapper& collection_
ASSIGN_RETURN_STATUS_DTO(status)
}
StatusDto::ObjectWrapper
WebRequestHandler::CreateHybridCollection(const milvus::server::web::OString& body) {
auto json_str = nlohmann::json::parse(body->c_str());
std::string collection_name = json_str["collection_name"];
// TODO(yukun): do checking
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>> field_types;
std::vector<std::pair<std::string, std::string>> field_extra_params;
std::vector<std::pair<std::string, uint64_t>> vector_dimensions;
for (auto& field : json_str["fields"]) {
std::string field_name = field["field_name"];
std::string field_type = field["field_type"];
auto extra_params = field["extra_params"];
if (field_type == "int8") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::INT8));
} else if (field_type == "int16") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::INT16));
} else if (field_type == "int32") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::INT32));
} else if (field_type == "int64") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::INT64));
} else if (field_type == "float") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::FLOAT));
} else if (field_type == "double") {
field_types.emplace_back(std::make_pair(field_name, engine::meta::hybrid::DataType::DOUBLE));
} else if (field_type == "vector") {
} else {
std::string msg = field_name + " has wrong field_type";
RETURN_STATUS_DTO(BODY_PARSE_FAIL, msg.c_str());
}
field_extra_params.emplace_back(std::make_pair(field_name, extra_params.dump()));
if (extra_params.contains("dimension")) {
vector_dimensions.emplace_back(std::make_pair(field_name, extra_params["dimension"].get<uint64_t>()));
}
}
auto status = request_handler_.CreateHybridCollection(context_ptr_, collection_name, field_types, vector_dimensions,
field_extra_params);
ASSIGN_RETURN_STATUS_DTO(status)
}
StatusDto::ObjectWrapper
WebRequestHandler::ShowTables(const OQueryParams& query_params, OString& result) {
int64_t offset = 0;
@ -1150,52 +1404,14 @@ WebRequestHandler::ShowSegments(const OString& collection_name, const OQueryPara
tag = query_params.get("partition_tag")->std_str();
}
CollectionInfo info;
std::string info;
status = request_handler_.ShowCollectionInfo(context_ptr_, collection_name->std_str(), info);
if (!status.ok()) {
ASSIGN_RETURN_STATUS_DTO(status)
}
typedef std::pair<std::string, SegmentStat> Pair;
std::vector<Pair> segments;
for (auto& par_stat : info.partitions_stat_) {
if (!(all_required || tag.empty() || tag == par_stat.tag_)) {
continue;
}
for (auto& seg_stat : par_stat.segments_stat_) {
auto segment_stat = std::pair<std::string, SegmentStat>(par_stat.tag_, seg_stat);
segments.push_back(segment_stat);
}
}
auto compare = [](Pair& a, Pair& b) -> bool { return a.second.name_ >= b.second.name_; };
std::sort(segments.begin(), segments.end(), compare);
int64_t size = segments.size();
int64_t iter_begin = 0;
int64_t iter_end = size;
if (!all_required) {
iter_begin = std::min(size, offset);
iter_end = std::min(size, offset + page_size);
}
nlohmann::json result_json;
if (segments.empty()) {
result_json["segments"] = std::vector<int64_t>();
} else {
nlohmann::json segs_json;
for (auto iter = iter_begin; iter < iter_end; iter++) {
nlohmann::json seg_json;
ParseSegmentStat(segments.at(iter).second, seg_json);
seg_json["partition_tag"] = segments.at(iter).first;
segs_json.push_back(seg_json);
}
result_json["segments"] = segs_json;
}
result_json["count"] = size;
nlohmann::json result_json = nlohmann::json::parse(info);
AddStatusToJson(result_json, status.code(), status.message());
response = result_json.dump().c_str();
ASSIGN_RETURN_STATUS_DTO(status)
@ -1295,6 +1511,106 @@ WebRequestHandler::Insert(const OString& collection_name, const OString& body, V
ASSIGN_RETURN_STATUS_DTO(status)
}
StatusDto::ObjectWrapper
WebRequestHandler::InsertEntity(const OString& collection_name, const milvus::server::web::OString& body,
VectorIdsDto::ObjectWrapper& ids_dto) {
if (nullptr == body.get() || body->getSize() == 0) {
RETURN_STATUS_DTO(BODY_FIELD_LOSS, "Request payload is required.")
}
auto body_json = nlohmann::json::parse(body->c_str());
std::string partition_tag = body_json["partition_tag"];
uint64_t row_num = body_json["row_num"];
std::unordered_map<std::string, engine::meta::hybrid::DataType> field_types;
auto status = request_handler_.DescribeHybridCollection(context_ptr_, collection_name->c_str(), field_types);
auto entities = body_json["entity"];
if (!entities.is_array()) {
RETURN_STATUS_DTO(ILLEGAL_BODY, "An entity must be an array");
}
std::vector<std::string> field_names;
std::vector<std::vector<uint8_t>> attr_values;
size_t attr_size = 0;
std::unordered_map<std::string, engine::VectorsData> vector_datas;
for (auto& entity : entities) {
std::string field_name = entity["field_name"];
field_names.emplace_back(field_name);
auto field_value = entity["field_value"];
std::vector<uint8_t> attr_value;
switch (field_types.at(field_name)) {
case engine::meta::hybrid::DataType::INT8:
case engine::meta::hybrid::DataType::INT16:
case engine::meta::hybrid::DataType::INT32:
case engine::meta::hybrid::DataType::INT64: {
std::vector<int64_t> value;
auto size = field_value.size();
value.resize(size);
attr_value.resize(size * sizeof(int64_t));
size_t offset = 0;
for (auto data : field_value) {
value[offset] = data.get<int64_t>();
++offset;
}
memcpy(attr_value.data(), value.data(), size * sizeof(int64_t));
attr_size += size * sizeof(int64_t);
attr_values.emplace_back(attr_value);
break;
}
case engine::meta::hybrid::DataType::FLOAT:
case engine::meta::hybrid::DataType::DOUBLE: {
std::vector<double> value;
auto size = field_value.size();
value.resize(size);
attr_value.resize(size * sizeof(double));
size_t offset = 0;
for (auto data : field_value) {
value[offset] = data.get<double>();
++offset;
}
memcpy(attr_value.data(), value.data(), size * sizeof(double));
attr_size += size * sizeof(double);
attr_values.emplace_back(attr_value);
break;
}
case engine::meta::hybrid::DataType::VECTOR: {
bool bin_flag;
status = IsBinaryTable(collection_name->c_str(), bin_flag);
if (!status.ok()) {
ASSIGN_RETURN_STATUS_DTO(status)
}
engine::VectorsData vectors;
CopyRecordsFromJson(field_value, vectors, bin_flag);
vector_datas.insert(std::make_pair(field_name, vectors));
}
default: {}
}
}
std::vector<uint8_t> attrs(attr_size, 0);
size_t attr_offset = 0;
for (auto& data : attr_values) {
memcpy(attrs.data() + attr_offset, data.data(), data.size());
attr_offset += data.size();
}
status = request_handler_.InsertEntity(context_ptr_, collection_name->c_str(), partition_tag, row_num, field_names,
attrs, vector_datas);
if (status.ok()) {
ids_dto->ids = ids_dto->ids->createShared();
for (auto& id : vector_datas.begin()->second.id_array_) {
ids_dto->ids->pushBack(std::to_string(id).c_str());
}
}
ASSIGN_RETURN_STATUS_DTO(status)
}
StatusDto::ObjectWrapper
WebRequestHandler::GetVector(const OString& collection_name, const OQueryParams& query_params, OString& response) {
int64_t id = 0;
@ -1337,6 +1653,8 @@ WebRequestHandler::VectorsOp(const OString& collection_name, const OString& payl
status = DeleteByIDs(collection_name->std_str(), payload_json["delete"], result_str);
} else if (payload_json.contains("search")) {
status = Search(collection_name->std_str(), payload_json["search"], result_str);
} else if (payload_json.contains("query")) {
status = HybridSearch(collection_name->c_str(), payload_json["query"], result_str);
} else {
status = Status(ILLEGAL_BODY, "Unknown body");
}

View File

@ -14,6 +14,7 @@
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
@ -26,7 +27,6 @@
#include "server/context/Context.h"
#include "server/delivery/RequestHandler.h"
#include "server/web_impl/Types.h"
#include "server/web_impl/dto/CmdDto.hpp"
#include "server/web_impl/dto/ConfigDto.hpp"
#include "server/web_impl/dto/DevicesDto.hpp"
#include "server/web_impl/dto/IndexDto.hpp"
@ -81,12 +81,6 @@ class WebRequestHandler {
void
AddStatusToJson(nlohmann::json& json, int64_t code, const std::string& msg);
Status
ParseSegmentStat(const SegmentStat& seg_stat, nlohmann::json& json);
Status
ParsePartitionStat(const PartitionStat& par_stat, nlohmann::json& json);
Status
IsBinaryTable(const std::string& collection_name, bool& bin);
@ -132,6 +126,15 @@ class WebRequestHandler {
Status
Search(const std::string& collection_name, const nlohmann::json& json, std::string& result_str);
Status
ProcessLeafQueryJson(const nlohmann::json& json, query::BooleanQueryPtr& boolean_query);
Status
ProcessBoolQueryJson(const nlohmann::json& query_json, query::BooleanQueryPtr& boolean_query);
Status
HybridSearch(const std::string& collection_name, const nlohmann::json& json, std::string& result_str);
Status
DeleteByIDs(const std::string& collection_name, const nlohmann::json& json, std::string& result_str);
@ -167,6 +170,9 @@ class WebRequestHandler {
StatusDto::ObjectWrapper
ShowTables(const OQueryParams& query_params, OString& result);
StatusDto::ObjectWrapper
CreateHybridCollection(const OString& body);
StatusDto::ObjectWrapper
GetTable(const OString& collection_name, const OQueryParams& query_params, OString& result);
@ -210,6 +216,9 @@ class WebRequestHandler {
StatusDto::ObjectWrapper
Insert(const OString& collection_name, const OString& body, VectorIdsDto::ObjectWrapper& ids_dto);
StatusDto::ObjectWrapper
InsertEntity(const OString& collection_name, const OString& body, VectorIdsDto::ObjectWrapper& ids_dto);
StatusDto::ObjectWrapper
GetVector(const OString& collection_name, const OQueryParams& query_params, OString& response);
@ -235,6 +244,7 @@ class WebRequestHandler {
private:
std::shared_ptr<Context> context_ptr_;
RequestHandler request_handler_;
std::unordered_map<std::string, engine::meta::hybrid::DataType> field_type_;
};
} // namespace web

View File

@ -256,7 +256,7 @@ CommonUtil::EraseFromCache(const std::string& item_key) {
#ifdef MILVUS_GPU_VERSION
server::Config& config = server::Config::GetInstance();
std::vector<int64_t> gpus;
Status s = config.GetGpuResourceConfigSearchResources(gpus);
config.GetGpuResourceConfigSearchResources(gpus);
for (auto& gpu : gpus) {
cache::GpuCacheMgr::GetInstance(gpu)->EraseItem(item_key);
}

View File

@ -54,27 +54,31 @@ RolloutHandler(const char* filename, std::size_t size, el::Level level) {
int ret;
std::string m(std::string(dir) + "/" + s);
s = m;
if (level == el::Level::Global) {
s.append("." + std::to_string(++global_idx));
ret = rename(m.c_str(), s.c_str());
} else if (level == el::Level::Debug) {
s.append("." + std::to_string(++debug_idx));
ret = rename(m.c_str(), s.c_str());
} else if (level == el::Level::Warning) {
s.append("." + std::to_string(++warning_idx));
ret = rename(m.c_str(), s.c_str());
} else if (level == el::Level::Trace) {
s.append("." + std::to_string(++trace_idx));
ret = rename(m.c_str(), s.c_str());
} else if (level == el::Level::Error) {
s.append("." + std::to_string(++error_idx));
ret = rename(m.c_str(), s.c_str());
} else if (level == el::Level::Fatal) {
s.append("." + std::to_string(++fatal_idx));
ret = rename(m.c_str(), s.c_str());
} else {
s.append("." + std::to_string(++global_idx));
ret = rename(m.c_str(), s.c_str());
switch (level) {
case el::Level::Debug:
s.append("." + std::to_string(++debug_idx));
ret = rename(m.c_str(), s.c_str());
break;
case el::Level::Warning:
s.append("." + std::to_string(++warning_idx));
ret = rename(m.c_str(), s.c_str());
break;
case el::Level::Trace:
s.append("." + std::to_string(++trace_idx));
ret = rename(m.c_str(), s.c_str());
break;
case el::Level::Error:
s.append("." + std::to_string(++error_idx));
ret = rename(m.c_str(), s.c_str());
break;
case el::Level::Fatal:
s.append("." + std::to_string(++fatal_idx));
ret = rename(m.c_str(), s.c_str());
break;
default:
s.append("." + std::to_string(++global_idx));
ret = rename(m.c_str(), s.c_str());
break;
}
}

View File

@ -45,7 +45,7 @@ aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/event scheduler_event_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/job scheduler_job_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/resource scheduler_resource_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/task scheduler_task_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/optimizer scheduler_optimizer_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/selector scheduler_selector_files)
set(scheduler_files
${scheduler_main_files}
${scheduler_action_files}
@ -53,7 +53,7 @@ set(scheduler_files
${scheduler_job_files}
${scheduler_resource_files}
${scheduler_task_files}
${scheduler_optimizer_files}
${scheduler_selector_files}
)
aux_source_directory(${MILVUS_THIRDPARTY_SRC}/easyloggingpp thirdparty_easyloggingpp_files)

View File

@ -33,7 +33,7 @@ namespace {
static const char* COLLECTION_NAME = "test_group";
static constexpr int64_t COLLECTION_DIM = 256;
static constexpr int64_t VECTOR_COUNT = 25000;
static constexpr int64_t INSERT_LOOP = 1000;
static constexpr int64_t INSERT_LOOP = 100;
static constexpr int64_t SECONDS_EACH_HOUR = 3600;
static constexpr int64_t DAY_SECONDS = 24 * 60 * 60;
@ -544,8 +544,9 @@ TEST_F(DBTest, SHUTDOWN_TEST) {
stat = db_->Compact(collection_info.collection_id_);
ASSERT_FALSE(stat.ok());
milvus::engine::VectorsData vector;
stat = db_->GetVectorByID(collection_info.collection_id_, 0, vector);
std::vector<milvus::engine::VectorsData> vectors;
std::vector<int64_t> id_array = {0};
stat = db_->GetVectorsByID(collection_info.collection_id_, id_array, vectors);
ASSERT_FALSE(stat.ok());
stat = db_->PreloadCollection(collection_info.collection_id_);
@ -1025,23 +1026,25 @@ TEST_F(DBTest2, SHOW_COLLECTION_INFO_TEST) {
ASSERT_TRUE(stat.ok());
{
milvus::engine::CollectionInfo collection_info;
std::string collection_info;
stat = db_->GetCollectionInfo(collection_name, collection_info);
ASSERT_TRUE(stat.ok());
int64_t row_count = 0;
for (auto& part : collection_info.partitions_stat_) {
row_count = 0;
for (auto& stat : part.segments_stat_) {
row_count += stat.row_count_;
ASSERT_EQ(stat.index_name_, "IDMAP");
ASSERT_GT(stat.data_size_, 0);
}
if (part.tag_ == milvus::engine::DEFAULT_PARTITON_TAG) {
ASSERT_EQ(row_count, VECTOR_COUNT);
} else {
ASSERT_EQ(row_count, INSERT_BATCH);
}
}
nlohmann::json json_info = nlohmann::json::parse(collection_info);
// for (auto& part : collection_info.partitions_stat_) {
// row_count = 0;
// for (auto& stat : part.segments_stat_) {
// row_count += stat.row_count_;
// ASSERT_EQ(stat.index_name_, "IDMAP");
// ASSERT_GT(stat.data_size_, 0);
// }
// if (part.tag_ == milvus::engine::DEFAULT_PARTITON_TAG) {
// ASSERT_EQ(row_count, VECTOR_COUNT);
// } else {
// ASSERT_EQ(row_count, INSERT_BATCH);
// }
// }
}
}
@ -1184,8 +1187,9 @@ TEST_F(DBTest2, FLUSH_NON_EXISTING_COLLECTION) {
}
TEST_F(DBTest2, GET_VECTOR_NON_EXISTING_COLLECTION) {
milvus::engine::VectorsData vector;
auto status = db_->GetVectorByID("non_existing", 0, vector);
std::vector<milvus::engine::VectorsData> vectors;
std::vector<int64_t> id_array = {0};
auto status = db_->GetVectorsByID("non_existing", id_array, vectors);
ASSERT_FALSE(status.ok());
}
@ -1203,19 +1207,32 @@ TEST_F(DBTest2, GET_VECTOR_BY_ID_TEST) {
stat = db_->CreatePartition(collection_info.collection_id_, partition_name, partition_tag);
ASSERT_TRUE(stat.ok());
std::vector<milvus::engine::VectorsData> vectors;
std::vector<int64_t> empty_array;
stat = db_->GetVectorsByID(COLLECTION_NAME, empty_array, vectors);
ASSERT_FALSE(stat.ok());
stat = db_->InsertVectors(collection_info.collection_id_, partition_tag, qxb);
ASSERT_TRUE(stat.ok());
db_->Flush(collection_info.collection_id_);
milvus::engine::VectorsData vector_data;
stat = db_->GetVectorByID(COLLECTION_NAME, qxb.id_array_[0], vector_data);
stat = db_->GetVectorsByID(COLLECTION_NAME, qxb.id_array_, vectors);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(vector_data.vector_count_, 1);
ASSERT_EQ(vector_data.float_data_.size(), COLLECTION_DIM);
ASSERT_EQ(vectors.size(), qxb.id_array_.size());
ASSERT_EQ(vectors[0].float_data_.size(), COLLECTION_DIM);
for (int64_t i = 0; i < COLLECTION_DIM; i++) {
ASSERT_FLOAT_EQ(vector_data.float_data_[i], qxb.float_data_[i]);
ASSERT_FLOAT_EQ(vectors[0].float_data_[i], qxb.float_data_[i]);
}
std::vector<int64_t> invalid_array = {-1, -1};
stat = db_->GetVectorsByID(COLLECTION_NAME, empty_array, vectors);
ASSERT_TRUE(stat.ok());
for (auto& vector : vectors) {
ASSERT_EQ(vector.vector_count_, 0);
ASSERT_TRUE(vector.float_data_.empty());
ASSERT_TRUE(vector.binary_data_.empty());
}
}
@ -1242,13 +1259,14 @@ TEST_F(DBTest2, GET_VECTOR_IDS_TEST) {
db_->Flush();
milvus::engine::CollectionInfo collection_info;
std::string collection_info;
stat = db_->GetCollectionInfo(COLLECTION_NAME, collection_info);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(collection_info.partitions_stat_.size(), 2UL);
ASSERT_FALSE(collection_info.empty());
std::string default_segment = collection_info.partitions_stat_[0].segments_stat_[0].name_;
std::string partition_segment = collection_info.partitions_stat_[1].segments_stat_[0].name_;
auto json = nlohmann::json::parse(collection_info);
std::string default_segment = json["partitions"].at(0)["segments"].at(0)["name"];
std::string partition_segment = json["partitions"].at(1)["segments"].at(0)["name"];
milvus::engine::IDNumbers vector_ids;
stat = db_->GetVectorIDs(COLLECTION_NAME, default_segment, vector_ids);

View File

@ -27,7 +27,7 @@ namespace {
static const char* COLLECTION_NAME = "test_group";
static constexpr int64_t COLLECTION_DIM = 256;
static constexpr int64_t VECTOR_COUNT = 25000;
static constexpr int64_t INSERT_LOOP = 1000;
static constexpr int64_t INSERT_LOOP = 100;
milvus::engine::meta::CollectionSchema
BuildCollectionSchema() {

View File

@ -125,7 +125,7 @@ TEST_F(DeleteTest, delete_in_mem) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk,
{{"nprobe", nprobe}}, search, result_ids, result_distances);
{{"nprobe", nprobe}}, search, result_ids, result_distances);
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
ASSERT_GT(result_distances[0], 1);
@ -194,7 +194,13 @@ TEST_F(DeleteTest, delete_on_disk) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}}, search, result_ids, result_distances);
collection_info.collection_id_,
tags,
topk,
{{"nprobe", nprobe}},
search,
result_ids,
result_distances);
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
ASSERT_GT(result_distances[0], 1);
@ -257,7 +263,13 @@ TEST_F(DeleteTest, delete_multiple_times) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}}, search, result_ids, result_distances);
collection_info.collection_id_,
tags,
topk,
{{"nprobe", nprobe}},
search,
result_ids,
result_distances);
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
ASSERT_GT(result_distances[0], 1);
@ -333,7 +345,13 @@ TEST_F(DeleteTest, delete_before_create_index) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}}, search, result_ids, result_distances);
collection_info.collection_id_,
tags,
topk,
{{"nprobe", nprobe}},
search,
result_ids,
result_distances);
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
ASSERT_GT(result_distances[0], 1);
@ -410,7 +428,13 @@ TEST_F(DeleteTest, delete_with_index) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}}, search, result_ids, result_distances);
collection_info.collection_id_,
tags,
topk,
{{"nprobe", nprobe}},
search,
result_ids,
result_distances);
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
ASSERT_GT(result_distances[0], 1);
@ -487,7 +511,13 @@ TEST_F(DeleteTest, delete_multiple_times_with_index) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}}, search, result_ids, result_distances);
collection_info.collection_id_,
tags,
topk,
{{"nprobe", nprobe}},
search,
result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_NE(result_ids[0], pair.first);
// ASSERT_LT(result_distances[0], 1e-4);
@ -534,7 +564,7 @@ TEST_F(DeleteTest, delete_single_vector) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, json_params, xb, result_ids, result_distances);
collection_info.collection_id_, tags, topk, json_params, xb, result_ids, result_distances);
ASSERT_TRUE(result_ids.empty());
ASSERT_TRUE(result_distances.empty());
// ASSERT_EQ(result_ids[0], -1);
@ -599,15 +629,15 @@ TEST_F(DeleteTest, delete_add_create_index) {
qb.vector_count_ = 1;
qb.id_array_.clear();
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, json_params, qb, result_ids, result_distances);
collection_info.collection_id_, tags, topk, json_params, qb, result_ids, result_distances);
ASSERT_EQ(result_ids[0], xb2.id_array_.front());
ASSERT_LT(result_distances[0], 1e-4);
result_ids.clear();
result_distances.clear();
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk,
json_params, ids_to_delete.front(), result_ids, result_distances);
stat = db_->QueryByIDs(dummy_context_, collection_info.collection_id_, tags, topk,
json_params, ids_to_delete, result_ids, result_distances);
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
@ -671,16 +701,16 @@ TEST_F(DeleteTest, delete_add_auto_flush) {
qb.vector_count_ = 1;
qb.id_array_.clear();
stat = db_->Query(dummy_context_,
collection_info.collection_id_, tags, topk, json_params, qb, result_ids, result_distances);
collection_info.collection_id_, tags, topk, json_params, qb, result_ids, result_distances);
ASSERT_EQ(result_ids[0], xb2.id_array_.front());
ASSERT_LT(result_distances[0], 1e-4);
result_ids.clear();
result_distances.clear();
stat = db_->QueryByID(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}},
ids_to_delete.front(), result_ids, result_distances);
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_, tags, topk, {{"nprobe", nprobe}},
ids_to_delete, result_ids, result_distances);
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
@ -730,12 +760,16 @@ TEST_F(CompactTest, compact_basic) {
milvus::engine::ResultDistances result_distances;
milvus::engine::VectorsData qb = xb;
for (auto& id : ids_to_delete) {
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, id, result_ids,
result_distances);
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_delete,
result_ids,
result_distances);
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
TEST_F(CompactTest, compact_with_index) {

View File

@ -88,19 +88,28 @@ BuildEntity(uint64_t n, uint64_t batch_index, milvus::engine::Entity& entity) {
vectors.id_array_.push_back(n * batch_index + i);
}
entity.vector_data_.insert(std::make_pair("field_3", vectors));
std::vector<std::string> value_0, value_1, value_2;
std::vector<int32_t> value_0;
std::vector<int64_t> value_1;
std::vector<float> value_2;
value_0.resize(n);
value_1.resize(n);
value_2.resize(n);
for (uint64_t i = 0; i < n; ++i) {
value_0[i] = std::to_string(i);
value_1[i] = std::to_string(i + n);
value_2[i] = std::to_string((i + 100) / (n + 1));
value_0[i] = i;
value_1[i] = i + n;
value_2[i] = (float)((i + 100) / (n + 1));
}
entity.entity_count_ = n;
entity.attr_data_.insert(std::make_pair("field_0", value_0));
entity.attr_data_.insert(std::make_pair("field_1", value_1));
entity.attr_data_.insert(std::make_pair("field_2", value_2));
size_t attr_size = n * (sizeof(int32_t) + sizeof(float) + sizeof(int64_t));
std::vector<uint8_t> attr_value(attr_size, 0);
size_t offset = 0;
memcpy(attr_value.data(), value_0.data(), n * sizeof(int32_t));
offset += n * sizeof(int32_t);
memcpy(attr_value.data() + offset, value_1.data(), n * sizeof(int64_t));
offset += n * sizeof(int64_t);
memcpy(attr_value.data() + offset, value_2.data(), n * sizeof(float));
entity.attr_value_ = attr_value;
}
void
@ -113,8 +122,12 @@ ConstructGeneralQuery(milvus::query::GeneralQueryPtr& general_query) {
left->bin->relation = milvus::query::QueryRelation::AND;
auto term_query = std::make_shared<milvus::query::TermQuery>();
std::vector<int64_t> field_value = {10, 20, 30, 40, 50};
std::vector<uint8_t> term_value;
term_value.resize(5 * sizeof(int64_t));
memcpy(term_value.data(), field_value.data(), 5 * sizeof(int64_t));
term_query->field_name = "field_0";
term_query->field_value = {"10", "20", "30", "40", "50"};
term_query->field_value = term_value;
term_query->boost = 1;
auto range_query = std::make_shared<milvus::query::RangeQuery>();
@ -174,22 +187,24 @@ TEST_F(DBTest, HYBRID_DB_TEST) {
milvus::engine::Entity entity;
BuildEntity(qb, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
std::vector<std::string> field_names = {"field_0", "field_1", "field_2"};
stat = db_->InsertEntities(TABLE_NAME, "", field_names, entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
// milvus::engine::CollectionIndex index;
// index.engine_type_ = (int)milvus::engine::EngineType::FAISS_IDMAP;
// index.extra_params_ = {{"nlist", 16384}};
//
// stat = db_->CreateIndex(TABLE_NAME, index);
// ASSERT_TRUE(stat.ok());
// milvus::engine::CollectionIndex index;
// index.engine_type_ = (int)milvus::engine::EngineType::FAISS_IDMAP;
// index.extra_params_ = {{"nlist", 16384}};
//
// stat = db_->CreateIndex(TABLE_NAME, index);
// ASSERT_TRUE(stat.ok());
}
TEST_F(DBTest, HYBRID_SEARCH_TEST) {
//#ifndef MILVUS_GPU_VERSION
//#ifndef MILVUS_GPU_VERSION
milvus::engine::meta::CollectionSchema collection_info;
milvus::engine::meta::hybrid::FieldsSchema fields_info;
std::unordered_map<std::string, milvus::engine::meta::hybrid::DataType> attr_type;
@ -208,7 +223,9 @@ TEST_F(DBTest, HYBRID_SEARCH_TEST) {
milvus::engine::Entity entity;
BuildEntity(qb, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
std::vector<std::string> field_names = {"field_0", "field_1", "field_2"};
stat = db_->InsertEntities(TABLE_NAME, "", field_names, entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
@ -226,7 +243,7 @@ TEST_F(DBTest, HYBRID_SEARCH_TEST) {
stat = db_->HybridQuery(dummy_context_, TABLE_NAME, tags, hybrid_context, general_query, attr_type, nq, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
//#endif
//#endif
}
TEST_F(DBTest, COMPACT_TEST) {
@ -248,7 +265,9 @@ TEST_F(DBTest, COMPACT_TEST) {
milvus::engine::Entity entity;
BuildEntity(vector_count, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
std::vector<std::string> field_names = {"field_0", "field_1", "field_2"};
stat = db_->InsertEntities(TABLE_NAME, "", field_names, entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
@ -273,11 +292,15 @@ TEST_F(DBTest, COMPACT_TEST) {
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
for (auto& id : ids_to_delete) {
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, id, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_delete,
result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}

View File

@ -61,9 +61,22 @@ BuildVectors(uint64_t n, milvus::engine::VectorsData& vectors) {
for (int j = 0; j < COLLECTION_DIM; j++) data[COLLECTION_DIM * i + j] = drand48();
}
}
void
CheckQueryResult(const std::vector<int64_t>& target_ids, int64_t topk, milvus::engine::ResultIds result_ids,
milvus::engine::ResultDistances result_distances) {
ASSERT_EQ(result_ids.size(), target_ids.size() * topk);
ASSERT_EQ(result_distances.size(), target_ids.size() * topk);
for (size_t i = 0; i < target_ids.size(); i++) {
ASSERT_EQ(result_ids[topk * i], target_ids[i]);
ASSERT_LT(result_distances[topk * i], 1e-3);
}
}
} // namespace
TEST_F(SearchByIdTest, basic) {
TEST_F(SearchByIdTest, BASIC_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -99,23 +112,53 @@ TEST_F(SearchByIdTest, basic) {
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto i : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, i, result_ids,
result_distances);
ASSERT_EQ(result_ids[0], i);
ASSERT_LT(result_distances[0], 1e-4);
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
CheckQueryResult(ids_to_search, topk, result_ids, result_distances);
// invalid id search
ids_to_search.clear();
for (int64_t i = 0; i < num_query; ++i) {
int64_t index = (i % 2 == 0) ? -1 : dis(gen);
ids_to_search.emplace_back(index);
}
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
ASSERT_EQ(result_ids.size(), ids_to_search.size() * topk);
ASSERT_EQ(result_distances.size(), ids_to_search.size() * topk);
for (size_t i = 0; i < ids_to_search.size(); i++) {
if (i % 2 == 0) {
ASSERT_EQ(result_ids[topk * i], -1);
ASSERT_FLOAT_EQ(result_distances[topk * i], std::numeric_limits<float>::max());
} else {
ASSERT_EQ(result_ids[topk * i], ids_to_search[i]);
ASSERT_LT(result_distances[topk * i], 1e-3);
}
}
}
TEST_F(SearchByIdTest, with_index) {
TEST_F(SearchByIdTest, WITH_INDEX_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -157,23 +200,26 @@ TEST_F(SearchByIdTest, with_index) {
stat = db_->CreateIndex(collection_info.collection_id_, index);
ASSERT_TRUE(stat.ok());
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto i : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, i, result_ids,
result_distances);
ASSERT_EQ(result_ids[0], i);
ASSERT_LT(result_distances[0], 1e-3);
}
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
CheckQueryResult(ids_to_search, topk, result_ids, result_distances);
}
TEST_F(SearchByIdTest, with_delete) {
TEST_F(SearchByIdTest, WITH_DELETE_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -218,23 +264,31 @@ TEST_F(SearchByIdTest, with_delete) {
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto i : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, i, result_ids,
result_distances);
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
ASSERT_EQ(result_ids.size(), ids_to_search.size() * topk);
ASSERT_EQ(result_distances.size(), ids_to_search.size() * topk);
for (size_t i = 0; i < result_ids.size(); i++) {
ASSERT_EQ(result_ids[i], -1);
}
}
TEST_F(GetVectorByIdTest, basic) {
TEST_F(GetVectorByIdTest, BASIC_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -270,28 +324,25 @@ TEST_F(GetVectorByIdTest, basic) {
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto id : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
milvus::engine::VectorsData vector;
stat = db_->GetVectorByID(collection_info.collection_id_, id, vector);
ASSERT_TRUE(stat.ok());
std::vector<milvus::engine::VectorsData> vectors;
stat = db_->GetVectorsByID(collection_info.collection_id_, ids_to_search, vectors);
ASSERT_TRUE(stat.ok());
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vector, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], id);
ASSERT_LT(result_distances[0], 1e-4);
}
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vectors[0], result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], ids_to_search[0]);
ASSERT_LT(result_distances[0], 1e-4);
}
TEST_F(GetVectorByIdTest, with_index) {
TEST_F(GetVectorByIdTest, WITH_INDEX_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -333,27 +384,25 @@ TEST_F(GetVectorByIdTest, with_index) {
stat = db_->CreateIndex(collection_info.collection_id_, index);
ASSERT_TRUE(stat.ok());
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto id : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
milvus::engine::VectorsData vector;
stat = db_->GetVectorByID(collection_info.collection_id_, id, vector);
ASSERT_TRUE(stat.ok());
std::vector<milvus::engine::VectorsData> vectors;
stat = db_->GetVectorsByID(collection_info.collection_id_, ids_to_search, vectors);
ASSERT_TRUE(stat.ok());
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vector, result_ids,
result_distances);
ASSERT_EQ(result_ids[0], id);
ASSERT_LT(result_distances[0], 1e-3);
}
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vectors[0], result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], ids_to_search[0]);
ASSERT_LT(result_distances[0], 1e-3);
}
TEST_F(GetVectorByIdTest, with_delete) {
TEST_F(GetVectorByIdTest, WITH_DELETE_TEST) {
milvus::engine::meta::CollectionSchema collection_info = BuildCollectionSchema();
auto stat = db_->CreateCollection(collection_info);
@ -398,21 +447,19 @@ TEST_F(GetVectorByIdTest, with_delete) {
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
for (auto id : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
milvus::engine::VectorsData vector;
stat = db_->GetVectorByID(collection_info.collection_id_, id, vector);
ASSERT_TRUE(stat.ok());
ASSERT_TRUE(vector.float_data_.empty());
std::vector<milvus::engine::VectorsData> vectors;
stat = db_->GetVectorsByID(collection_info.collection_id_, ids_to_search, vectors);
ASSERT_TRUE(stat.ok());
for (auto& vector : vectors) {
ASSERT_EQ(vector.vector_count_, 0);
}
}
TEST_F(SearchByIdTest, BINARY) {
TEST_F(SearchByIdTest, BINARY_TEST) {
milvus::engine::meta::CollectionSchema collection_info;
collection_info.dimension_ = COLLECTION_DIM;
collection_info.collection_id_ = GetCollectionName();
@ -472,34 +519,64 @@ TEST_F(SearchByIdTest, BINARY) {
ASSERT_TRUE(stat.ok());
ASSERT_EQ(row_count, nb * insert_loop);
const int topk = 10, nprobe = 10;
const int64_t topk = 10, nprobe = 10;
milvus::json json_params = {{"nprobe", nprobe}};
for (auto id : ids_to_search) {
// std::cout << "xxxxxxxxxxxxxxxxxxxx " << i << std::endl;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
milvus::engine::VectorsData vector;
stat = db_->GetVectorByID(collection_info.collection_id_, id, vector);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(vector.vector_count_, 1);
std::vector<milvus::engine::VectorsData> vectors;
stat = db_->GetVectorsByID(collection_info.collection_id_, ids_to_search, vectors);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(vectors.size(), ids_to_search.size());
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vector, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], id);
ASSERT_LT(result_distances[0], 1e-4);
stat = db_->Query(dummy_context_, collection_info.collection_id_, tags, topk, json_params, vectors[0], result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], ids_to_search[0]);
ASSERT_LT(result_distances[0], 1e-4);
tags.clear();
result_ids.clear();
result_distances.clear();
tags.clear();
result_ids.clear();
result_distances.clear();
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, id, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], id);
ASSERT_LT(result_distances[0], 1e-4);
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
CheckQueryResult(ids_to_search, topk, result_ids, result_distances);
// invalid id search
ids_to_search.clear();
for (int64_t i = 0; i < num_query; ++i) {
int64_t index = (i % 2 == 0) ? -1 : dis(gen);
ids_to_search.emplace_back(index);
}
stat = db_->QueryByIDs(dummy_context_,
collection_info.collection_id_,
tags,
topk,
json_params,
ids_to_search,
result_ids,
result_distances);
ASSERT_EQ(result_ids.size(), ids_to_search.size() * topk);
ASSERT_EQ(result_distances.size(), ids_to_search.size() * topk);
for (size_t i = 0; i < ids_to_search.size(); i++) {
if (i % 2 == 0) {
ASSERT_EQ(result_ids[topk * i], -1);
ASSERT_FLOAT_EQ(result_distances[topk * i], std::numeric_limits<float>::max());
} else {
ASSERT_EQ(result_ids[topk * i], ids_to_search[i]);
ASSERT_LT(result_distances[topk * i], 1e-3);
}
}
}

View File

@ -21,7 +21,7 @@ set(test_files
${CMAKE_CURRENT_SOURCE_DIR}/test_scheduler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_task.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_job.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_optimizer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_selector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_tasktable.cpp)
add_executable(test_scheduler

View File

@ -14,15 +14,15 @@
#include "scheduler/task/BuildIndexTask.h"
#include "scheduler/task/SearchTask.h"
#include "scheduler/optimizer/FaissIVFFlatPass.h"
#include "scheduler/SchedInst.h"
#include "scheduler/resource/CpuResource.h"
#include "scheduler/optimizer/BuildIndexPass.h"
#include "scheduler/optimizer/FaissFlatPass.h"
#include "scheduler/optimizer/FaissIVFPQPass.h"
#include "scheduler/optimizer/FaissIVFSQ8HPass.h"
#include "scheduler/optimizer/FaissIVFSQ8Pass.h"
#include "scheduler/optimizer/FallbackPass.h"
#include "scheduler/selector/BuildIndexPass.h"
#include "scheduler/selector/FaissFlatPass.h"
#include "scheduler/selector/FaissIVFFlatPass.h"
#include "scheduler/selector/FaissIVFPQPass.h"
#include "scheduler/selector/FaissIVFSQ8HPass.h"
#include "scheduler/selector/FaissIVFSQ8Pass.h"
#include "scheduler/selector/FallbackPass.h"
namespace milvus {
namespace scheduler {

View File

@ -935,19 +935,25 @@ TEST_F(RpcHandlerTest, CMD_TEST) {
command.set_cmd("tasktable");
handler->Cmd(&context, &command, &reply);
ASSERT_EQ(reply.status().error_code(), ::grpc::Status::OK.error_code());
command.set_cmd("test");
handler->Cmd(&context, &command, &reply);
ASSERT_EQ(reply.status().error_code(), ::grpc::Status::OK.error_code());
command.set_cmd("status");
handler->Cmd(&context, &command, &reply);
ASSERT_EQ(reply.status().error_code(), ::grpc::Status::OK.error_code());
command.set_cmd("mode");
handler->Cmd(&context, &command, &reply);
ASSERT_EQ(reply.status().error_code(), ::grpc::Status::OK.error_code());
command.set_cmd("build_commit_id");
handler->Cmd(&context, &command, &reply);
ASSERT_EQ(reply.status().error_code(), ::grpc::Status::OK.error_code());
command.set_cmd("set_config");
handler->Cmd(&context, &command, &reply);
command.set_cmd("get_config");
handler->Cmd(&context, &command, &reply);
}
@ -977,22 +983,18 @@ TEST_F(RpcHandlerTest, HYBRID_TEST) {
milvus::grpc::HEntityIDs entity_ids;
insert_param.set_collection_name("test_hybrid");
std::vector<std::string> numerica_value;
numerica_value.resize(row_num);
for (uint64_t i = 0; i < row_num; i++) {
numerica_value[i] = std::to_string(i);
}
auto entity = insert_param.mutable_entities();
auto field_name_0 = entity->add_field_names();
*field_name_0 = "field_0";
auto field_name_1 = entity->add_field_names();
*field_name_1 = "field_1";
auto records_0 = entity->add_attr_records();
for (auto value : numerica_value) {
auto record = records_0->add_value();
*record = value;
entity->set_row_num(row_num);
std::vector<int64_t> field_value(row_num, 0);
for (uint64_t i = 0; i < row_num; i++) {
field_value[i] = i;
}
entity->set_attr_records(field_value.data(), row_num * sizeof(int64_t));
std::vector<std::vector<float>> vector_field;
vector_field.resize(row_num);
@ -1012,7 +1014,6 @@ TEST_F(RpcHandlerTest, HYBRID_TEST) {
handler->InsertEntity(&context, &insert_param, &entity_ids);
ASSERT_EQ(entity_ids.entity_id_array_size(), row_num);
// TODO(yukun): Hybrid Search
uint64_t nq = 10;
uint64_t topk = 10;
milvus::grpc::HSearchParam search_param;
@ -1023,11 +1024,13 @@ TEST_F(RpcHandlerTest, HYBRID_TEST) {
auto boolean_query_2 = general_query_1->mutable_boolean_query();
auto term_query = boolean_query_2->add_general_query()->mutable_term_query();
term_query->set_field_name("field_0");
std::vector<int64_t> term_value(nq, 0);
for (uint64_t i = 0; i < nq; ++i) {
auto value = std::to_string(i + nq);
auto term = term_query->add_values();
*term = value;
term_value[i] = i + nq;
}
term_query->set_value_num(nq);
term_query->set_values(term_value.data(), nq * sizeof(int64_t));
auto vector_query = boolean_query_2->add_general_query()->mutable_vector_query();
vector_query->set_field_name("field_1");
vector_query->set_topk(topk);

Some files were not shown because too many files have changed in this diff Show More