mirror of
https://gitee.com/milvus-io/milvus.git
synced 2026-01-05 18:31:59 +08:00
Remove unused directory (#16419)
Signed-off-by: yudong.cai <yudong.cai@zilliz.com>
This commit is contained in:
parent
bb7a0766fe
commit
b09e56ff81
@ -1,80 +0,0 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# 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.
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# library
|
||||
set( VALUE_SRCS config/ConfigInit.cpp
|
||||
config/ConfigMgr.h
|
||||
config/ConfigMgr.cpp
|
||||
config/ServerConfig.h
|
||||
config/ServerConfig.cpp
|
||||
status/StatusInit.cpp
|
||||
status/StatusMgr.h
|
||||
status/StatusMgr.cpp
|
||||
status/ServerStatus.h
|
||||
status/ServerStatus.cpp
|
||||
Value.h
|
||||
ValueMgr.h
|
||||
ValueMgr.cpp
|
||||
ValueType.h
|
||||
ValueType.cpp
|
||||
)
|
||||
|
||||
set( VALUE_LIBS yaml-cpp)
|
||||
|
||||
create_library(
|
||||
TARGET value
|
||||
SRCS ${VALUE_SRCS}
|
||||
LIBS ${VALUE_LIBS}
|
||||
)
|
||||
|
||||
if ( BUILD_UNIT_TEST )
|
||||
create_library(
|
||||
TARGET value-test
|
||||
SRCS ${VALUE_SRCS}
|
||||
LIBS ${VALUE_LIBS})
|
||||
|
||||
set(GTEST_LIBS gtest gtest_main gmock gmock_main)
|
||||
|
||||
create_executable(
|
||||
TARGET ConfigMgrTest
|
||||
SRCS config/ConfigMgrTest
|
||||
LIBS value-test ${GTEST_LIBS}
|
||||
DEFS ""
|
||||
)
|
||||
|
||||
add_test ( NAME ConfigMgrTest
|
||||
COMMAND $<TARGET_FILE:ConfigMgrTest>
|
||||
)
|
||||
|
||||
create_executable(
|
||||
TARGET ServerConfigTest
|
||||
SRCS config/ServerConfigTest
|
||||
LIBS value-fiu ${GTEST_LIBS}
|
||||
DEFS ""
|
||||
)
|
||||
|
||||
add_test ( NAME ServerConfigTest
|
||||
COMMAND $<TARGET_FILE:ServerConfigTest>
|
||||
)
|
||||
|
||||
create_executable(
|
||||
TARGET ValueTypeTest
|
||||
SRCS ValueTypeTest1 ValueTypeTest2
|
||||
LIBS value-test ${GTEST_LIBS}
|
||||
DEFS ""
|
||||
)
|
||||
|
||||
add_test ( NAME ValueTypeTest
|
||||
COMMAND $<TARGET_FILE:ValueTypeTest>
|
||||
)
|
||||
endif()
|
||||
@ -1,39 +0,0 @@
|
||||
// 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 <mutex>
|
||||
|
||||
namespace milvus {
|
||||
|
||||
template <typename T>
|
||||
class Value {
|
||||
public:
|
||||
const T&
|
||||
operator()() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
Value&
|
||||
operator=(T value) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,72 +0,0 @@
|
||||
// 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 "value/ValueMgr.h"
|
||||
#include "utils/Json.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
void
|
||||
BaseValueMgr::Attach(const std::string& name, ValueObserver* observer) {
|
||||
std::lock_guard<std::mutex> lock(observer_mutex_);
|
||||
observers_[name].push_back(observer);
|
||||
}
|
||||
|
||||
void
|
||||
BaseValueMgr::Detach(const std::string& name, ValueObserver* observer) {
|
||||
std::lock_guard<std::mutex> lock(observer_mutex_);
|
||||
if (observers_.find(name) == observers_.end()) {
|
||||
return;
|
||||
}
|
||||
auto& ob_list = observers_[name];
|
||||
ob_list.remove(observer);
|
||||
}
|
||||
|
||||
void
|
||||
BaseValueMgr::Notify(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(observer_mutex_);
|
||||
if (observers_.find(name) == observers_.end()) {
|
||||
return;
|
||||
}
|
||||
auto& ob_list = observers_[name];
|
||||
for (auto& ob : ob_list) {
|
||||
ob->ValueUpdate(name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ValueMgr::Init() {
|
||||
for (auto& kv : value_list_) {
|
||||
kv.second->Init();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
ValueMgr::Dump() const {
|
||||
std::stringstream ss;
|
||||
for (auto& kv : value_list_) {
|
||||
auto& config = kv.second;
|
||||
ss << config->name_ << ": " << config->Get() << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
ValueMgr::JsonDump() const {
|
||||
json config_list;
|
||||
for (auto& kv : value_list_) {
|
||||
auto& config = kv.second;
|
||||
config_list[config->name_] = config->Get();
|
||||
}
|
||||
return config_list.dump();
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,85 +0,0 @@
|
||||
// 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 <list>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
class ValueObserver {
|
||||
public:
|
||||
virtual ~ValueObserver() = default;
|
||||
|
||||
virtual void
|
||||
ValueUpdate(const std::string& name) = 0;
|
||||
};
|
||||
|
||||
class BaseValueMgr {
|
||||
protected:
|
||||
BaseValueMgr() = default;
|
||||
|
||||
public:
|
||||
// Shared pointer should not be used here
|
||||
void
|
||||
Attach(const std::string& name, ValueObserver* observer);
|
||||
|
||||
void
|
||||
Detach(const std::string& name, ValueObserver* observer);
|
||||
|
||||
protected:
|
||||
virtual void
|
||||
Notify(const std::string& name);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::list<ValueObserver*>> observers_;
|
||||
std::mutex observer_mutex_;
|
||||
};
|
||||
|
||||
class ValueMgr : public BaseValueMgr {
|
||||
public:
|
||||
explicit ValueMgr(std::unordered_map<std::string, BaseValuePtr> init_list) : value_list_(std::move(init_list)) {
|
||||
}
|
||||
|
||||
ValueMgr(const ValueMgr&) = delete;
|
||||
ValueMgr&
|
||||
operator=(const ValueMgr&) = delete;
|
||||
|
||||
ValueMgr(ValueMgr&&) = delete;
|
||||
ValueMgr&
|
||||
operator=(ValueMgr&&) = delete;
|
||||
|
||||
public:
|
||||
void
|
||||
Init();
|
||||
|
||||
virtual void
|
||||
Set(const std::string& name, const std::string& value, bool update) = 0;
|
||||
|
||||
virtual std::string
|
||||
Get(const std::string& name) const = 0;
|
||||
|
||||
std::string
|
||||
Dump() const;
|
||||
|
||||
std::string
|
||||
JsonDump() const;
|
||||
|
||||
protected:
|
||||
const std::unordered_map<std::string, BaseValuePtr> value_list_;
|
||||
};
|
||||
} // namespace milvus
|
||||
@ -1,627 +0,0 @@
|
||||
// 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 "value/ValueType.h"
|
||||
|
||||
#include <strings.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
std::unordered_map<std::string, int64_t> BYTE_UNITS = {
|
||||
{"b", 1},
|
||||
{"k", 1024},
|
||||
{"m", 1024 * 1024},
|
||||
{"g", 1024 * 1024 * 1024},
|
||||
};
|
||||
|
||||
std::map<std::string, int64_t> TIME_UNITS = {
|
||||
// {"seconds", 1ll},
|
||||
// {"minutes", 1ll * 60},
|
||||
{"hours", 1ll * 60 * 60},
|
||||
{"days", 1ll * 60 * 60 * 24},
|
||||
};
|
||||
|
||||
bool
|
||||
is_integer(const std::string& s) {
|
||||
if (not s.empty() && (std::isdigit(s[0]) || s[0] == '-')) {
|
||||
auto ss = s.substr(1);
|
||||
return std::find_if(ss.begin(), ss.end(), [](unsigned char c) { return !std::isdigit(c); }) == ss.end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
is_number(const std::string& s) {
|
||||
return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
||||
}
|
||||
|
||||
bool
|
||||
is_alpha(const std::string& s) {
|
||||
return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isalpha(c); }) == s.end();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
boundary_check(T val, T lower_bound, T upper_bound) {
|
||||
return lower_bound <= val && val <= upper_bound;
|
||||
}
|
||||
|
||||
bool
|
||||
parse_bool(const std::string& str, std::string& err) {
|
||||
if (!strcasecmp(str.c_str(), "true")) {
|
||||
return true;
|
||||
} else if (!strcasecmp(str.c_str(), "false")) {
|
||||
return false;
|
||||
} else {
|
||||
err = "The specified value must be true or false";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
str_tolower(std::string s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
return s;
|
||||
}
|
||||
|
||||
int64_t
|
||||
parse_bytes(const std::string& str, std::string& err) {
|
||||
try {
|
||||
if (str.find_first_of('-') != std::string::npos) {
|
||||
std::stringstream ss;
|
||||
ss << "The specified value for memory (" << str << ") should be a positive integer.";
|
||||
err = ss.str();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string s = str;
|
||||
if (is_number(s)) {
|
||||
return std::stoll(s);
|
||||
}
|
||||
if (s.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto last_two = s.substr(s.length() - 2, 2);
|
||||
auto last_one = s.substr(s.length() - 1);
|
||||
if (is_alpha(last_two) && is_alpha(last_one)) {
|
||||
if (last_one == "b" or last_one == "B") {
|
||||
s = s.substr(0, s.length() - 1);
|
||||
}
|
||||
}
|
||||
auto& units = BYTE_UNITS;
|
||||
auto suffix = str_tolower(s.substr(s.length() - 1));
|
||||
|
||||
std::string digits_part;
|
||||
if (is_number(suffix)) {
|
||||
digits_part = s;
|
||||
suffix = 'b';
|
||||
} else {
|
||||
digits_part = s.substr(0, s.length() - 1);
|
||||
}
|
||||
|
||||
if (is_number(digits_part) && (units.find(suffix) != units.end() || is_number(suffix))) {
|
||||
auto digits = std::stoll(digits_part);
|
||||
return digits * units[suffix];
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << "The specified value for memory (" << str << ") should specify the units."
|
||||
<< " The postfix should be one of the `b` `k` `m` `g` characters.";
|
||||
err = ss.str();
|
||||
}
|
||||
} catch (...) {
|
||||
err = "Unknown error happened on parse bytes.";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t
|
||||
parse_time(const std::string& str, std::string& err) {
|
||||
try {
|
||||
const std::regex regex(R"(\s*([0-9]+)\s*(seconds|minutes|hours|days)\s*)");
|
||||
std::smatch base_match;
|
||||
auto& units = TIME_UNITS;
|
||||
if (std::regex_match(str, base_match, regex) && base_match.size() == 3 &&
|
||||
units.find(base_match[2].str()) != units.end()) {
|
||||
return stoll(base_match[1].str()) * units[base_match[2].str()];
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << "The specified value for time (" << str << ") should specify the units."
|
||||
<< " The postfix should be one of the ";
|
||||
for (auto& pair : units) {
|
||||
ss << "`" << pair.first << "` ";
|
||||
}
|
||||
ss << "words.";
|
||||
err = ss.str();
|
||||
}
|
||||
} catch (...) {
|
||||
err = "Unknown error happened on parse time.";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Use (void) to silent unused warnings.
|
||||
#define assertm(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace milvus {
|
||||
|
||||
std::vector<std::string>
|
||||
OptionValue(const valueEnum& ce) {
|
||||
std::vector<std::string> ret;
|
||||
for (auto& e : ce) {
|
||||
ret.emplace_back(e.first);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BaseValue::BaseValue(const char* name, const char* alias, bool modifiable)
|
||||
: name_(name), alias_(alias), modifiable_(modifiable) {
|
||||
}
|
||||
|
||||
void
|
||||
BaseValue::Init() {
|
||||
assertm(not inited_, "already initialized");
|
||||
inited_ = true;
|
||||
}
|
||||
|
||||
BoolValue::BoolValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
Value<bool>& config,
|
||||
bool default_value,
|
||||
std::function<bool(bool val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
BoolValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
BoolValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Parse from string */
|
||||
std::string err;
|
||||
bool value = parse_bool(val, err);
|
||||
if (not err.empty()) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
BoolValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
return config_() ? "true" : "false";
|
||||
}
|
||||
|
||||
StringValue::StringValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
Value<std::string>& config,
|
||||
const char* default_value,
|
||||
std::function<bool(const std::string& val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
StringValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
StringValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
std::string err;
|
||||
if (is_valid_fn_ && not is_valid_fn_(val, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = val;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
StringValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
return config_();
|
||||
}
|
||||
|
||||
EnumValue::EnumValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
valueEnum* enumd,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
enum_value_(enumd),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
EnumValue::Init() {
|
||||
BaseValue::Init();
|
||||
assert(enum_value_ != nullptr);
|
||||
assertm(not enum_value_->empty(), "enum value empty");
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
EnumValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Check if value exist */
|
||||
if (enum_value_->find(val) == enum_value_->end()) {
|
||||
auto option_values = OptionValue(*enum_value_);
|
||||
throw EnumValueNotFound(name_, val, std::move(option_values));
|
||||
}
|
||||
|
||||
int64_t value = enum_value_->at(val);
|
||||
|
||||
/* Validate */
|
||||
std::string err;
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
EnumValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
auto val = config_();
|
||||
for (auto& it : *enum_value_) {
|
||||
if (val == it.second) {
|
||||
return it.first;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
IntegerValue::IntegerValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
lower_bound_(lower_bound),
|
||||
upper_bound_(upper_bound),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
IntegerValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
IntegerValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Check if it is an integer */
|
||||
if (not is_integer(val)) {
|
||||
throw Invalid(name_, val, "Not an integer.");
|
||||
}
|
||||
|
||||
/* Parse from string */
|
||||
int64_t value = std::stoll(val);
|
||||
|
||||
/* Boundary check */
|
||||
if (not boundary_check<int64_t>(value, lower_bound_, upper_bound_)) {
|
||||
throw OutOfRange<int64_t>(name_, val, lower_bound_, upper_bound_);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
std::string err;
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
IntegerValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
return std::to_string(config_());
|
||||
}
|
||||
|
||||
FloatingValue::FloatingValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
double lower_bound,
|
||||
double upper_bound,
|
||||
Value<double>& config,
|
||||
double default_value,
|
||||
std::function<bool(double val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
lower_bound_(lower_bound),
|
||||
upper_bound_(upper_bound),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
FloatingValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
FloatingValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Parse from string */
|
||||
double value = std::stod(val);
|
||||
|
||||
/* Boundary check */
|
||||
if (not boundary_check<double>(value, lower_bound_, upper_bound_)) {
|
||||
throw OutOfRange<double>(name_, val, lower_bound_, upper_bound_);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
std::string err;
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
FloatingValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
return std::to_string(config_());
|
||||
}
|
||||
|
||||
SizeValue::SizeValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
lower_bound_(lower_bound),
|
||||
upper_bound_(upper_bound),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
SizeValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
SizeValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Parse from string */
|
||||
std::string err;
|
||||
int64_t value = parse_bytes(val, err);
|
||||
if (not err.empty()) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Boundary check */
|
||||
if (not boundary_check<int64_t>(value, lower_bound_, upper_bound_)) {
|
||||
throw OutOfRange<int64_t>(name_, val, lower_bound_, upper_bound_);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
SizeValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
auto val = config_();
|
||||
const int64_t gb = 1024ll * 1024 * 1024;
|
||||
const int64_t mb = 1024ll * 1024;
|
||||
const int64_t kb = 1024ll;
|
||||
if (val % gb == 0) {
|
||||
return std::to_string(val / gb) + "GB";
|
||||
} else if (val % mb == 0) {
|
||||
return std::to_string(val / mb) + "MB";
|
||||
} else if (val % kb == 0) {
|
||||
return std::to_string(val / kb) + "KB";
|
||||
} else {
|
||||
return std::to_string(val);
|
||||
}
|
||||
}
|
||||
|
||||
TimeValue::TimeValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn)
|
||||
: BaseValue(name, alias, modifiable),
|
||||
config_(config),
|
||||
lower_bound_(lower_bound),
|
||||
upper_bound_(upper_bound),
|
||||
default_value_(default_value),
|
||||
is_valid_fn_(std::move(is_valid_fn)) {
|
||||
}
|
||||
|
||||
void
|
||||
TimeValue::Init() {
|
||||
BaseValue::Init();
|
||||
config_ = default_value_;
|
||||
}
|
||||
|
||||
void
|
||||
TimeValue::Set(const std::string& val, bool update) {
|
||||
assertm(inited_, "uninitialized");
|
||||
try {
|
||||
/* Check modifiable */
|
||||
if (update and not modifiable_) {
|
||||
throw Immutable(name_, val);
|
||||
}
|
||||
|
||||
/* Parse from string */
|
||||
std::string err;
|
||||
int64_t value = parse_time(val, err);
|
||||
if (not err.empty()) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Boundary check */
|
||||
if (not boundary_check<int64_t>(value, lower_bound_, upper_bound_)) {
|
||||
throw OutOfRange<int64_t>(name_, val, lower_bound_, upper_bound_);
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
if (is_valid_fn_ && not is_valid_fn_(value, err)) {
|
||||
throw Invalid(name_, val, err);
|
||||
}
|
||||
|
||||
/* Set value */
|
||||
config_ = value;
|
||||
} catch (ValueError& e) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw Unexpected(name_, val);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
TimeValue::Get() {
|
||||
assertm(inited_, "uninitialized");
|
||||
auto val = config_();
|
||||
const int64_t second = 1ll;
|
||||
const int64_t minute = second * 60;
|
||||
const int64_t hour = minute * 60;
|
||||
const int64_t day = hour * 24;
|
||||
if (val % day == 0) {
|
||||
return std::to_string(val / day) + "days";
|
||||
} else if (val % hour == 0) {
|
||||
return std::to_string(val / hour) + "hours";
|
||||
} else if (val % minute == 0) {
|
||||
return std::to_string(val / minute) + "minutes";
|
||||
} else {
|
||||
return std::to_string(val) + "seconds";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,354 +0,0 @@
|
||||
// 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 <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "value/Value.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
using valueEnum = const std::unordered_map<std::string, int64_t>;
|
||||
std::vector<std::string>
|
||||
OptionValue(const valueEnum& ce);
|
||||
|
||||
struct ValueError : public std::exception {
|
||||
explicit ValueError(const std::string& name, const std::string& value) : name_(name), value_(value) {
|
||||
}
|
||||
|
||||
virtual std::string
|
||||
message() = 0;
|
||||
|
||||
protected:
|
||||
const std::string name_;
|
||||
const std::string value_;
|
||||
};
|
||||
|
||||
struct Immutable : public ValueError {
|
||||
explicit Immutable(const std::string& name, const std::string& value) : ValueError(name, value) {
|
||||
}
|
||||
|
||||
std::string
|
||||
message() override {
|
||||
return "Config " + name_ + " is immutable.";
|
||||
}
|
||||
};
|
||||
|
||||
struct EnumValueNotFound : public ValueError {
|
||||
EnumValueNotFound(const std::string& name, const std::string& value, std::vector<std::string> option_values)
|
||||
: ValueError(name, value), option_values_(std::move(option_values)) {
|
||||
}
|
||||
|
||||
std::string
|
||||
message() override {
|
||||
std::stringstream ss;
|
||||
ss << "Config " << name_ << "(" << value_ << ") must be one of following: ";
|
||||
for (size_t i = 0; i < option_values_.size() - 1; ++i) {
|
||||
ss << option_values_[i] << ", ";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> option_values_;
|
||||
};
|
||||
|
||||
struct Invalid : public ValueError {
|
||||
Invalid(const std::string& name, const std::string& value, const std::string& reason)
|
||||
: ValueError(name, value), reason_(reason) {
|
||||
}
|
||||
|
||||
std::string
|
||||
message() override {
|
||||
return value_ + " is invalid for config " + name_ + ": " + reason_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string reason_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct OutOfRange : public ValueError {
|
||||
OutOfRange(const std::string& name, const std::string& value, T lower_bound, T upper_bound)
|
||||
: ValueError(name, value), lower_bound_(lower_bound), upper_bound_(upper_bound) {
|
||||
}
|
||||
|
||||
std::string
|
||||
message() override {
|
||||
return "Config " + name_ + "(" + value_ + ") must in range [" + std::to_string(lower_bound_) + ", " +
|
||||
std::to_string(upper_bound_) + "].";
|
||||
}
|
||||
|
||||
private:
|
||||
T lower_bound_;
|
||||
T upper_bound_;
|
||||
};
|
||||
|
||||
struct Unexpected : public ValueError {
|
||||
Unexpected(const std::string& name, const std::string& value) : ValueError(name, value) {
|
||||
}
|
||||
|
||||
std::string
|
||||
message() override {
|
||||
return "An unknown error occurred while setting " + name_ + " as " + value_;
|
||||
}
|
||||
};
|
||||
|
||||
class BaseValue {
|
||||
public:
|
||||
BaseValue(const char* name, const char* alias, bool modifiable);
|
||||
virtual ~BaseValue() = default;
|
||||
|
||||
public:
|
||||
bool inited_ = false;
|
||||
const char* name_;
|
||||
const char* alias_;
|
||||
const bool modifiable_;
|
||||
|
||||
public:
|
||||
virtual void
|
||||
Init();
|
||||
|
||||
virtual void
|
||||
Set(const std::string& value, bool update) = 0;
|
||||
|
||||
virtual std::string
|
||||
Get() = 0;
|
||||
};
|
||||
using BaseValuePtr = std::shared_ptr<BaseValue>;
|
||||
|
||||
class BoolValue : public BaseValue {
|
||||
public:
|
||||
BoolValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
Value<bool>& config,
|
||||
bool default_value,
|
||||
std::function<bool(bool val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<bool>& config_;
|
||||
const bool default_value_;
|
||||
std::function<bool(bool val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class StringValue : public BaseValue {
|
||||
public:
|
||||
StringValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
Value<std::string>& config,
|
||||
const char* default_value,
|
||||
std::function<bool(const std::string& val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<std::string>& config_;
|
||||
const char* default_value_;
|
||||
std::function<bool(const std::string& val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class EnumValue : public BaseValue {
|
||||
public:
|
||||
EnumValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
valueEnum* enumd,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<int64_t>& config_;
|
||||
valueEnum* enum_value_;
|
||||
const int64_t default_value_;
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class IntegerValue : public BaseValue {
|
||||
public:
|
||||
IntegerValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<int64_t>& config_;
|
||||
int64_t lower_bound_;
|
||||
int64_t upper_bound_;
|
||||
const int64_t default_value_;
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class FloatingValue : public BaseValue {
|
||||
public:
|
||||
FloatingValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
double lower_bound,
|
||||
double upper_bound,
|
||||
Value<double>& config,
|
||||
double default_value,
|
||||
std::function<bool(double val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<double>& config_;
|
||||
double lower_bound_;
|
||||
double upper_bound_;
|
||||
const double default_value_;
|
||||
std::function<bool(double val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class SizeValue : public BaseValue {
|
||||
public:
|
||||
SizeValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<int64_t>& config_;
|
||||
int64_t lower_bound_;
|
||||
int64_t upper_bound_;
|
||||
const int64_t default_value_;
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
class TimeValue : public BaseValue {
|
||||
public:
|
||||
TimeValue(const char* name,
|
||||
const char* alias,
|
||||
bool modifiable,
|
||||
int64_t lower_bound,
|
||||
int64_t upper_bound,
|
||||
Value<int64_t>& config,
|
||||
int64_t default_value,
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn = nullptr);
|
||||
|
||||
private:
|
||||
Value<int64_t>& config_;
|
||||
int64_t lower_bound_;
|
||||
int64_t upper_bound_;
|
||||
const int64_t default_value_;
|
||||
std::function<bool(int64_t val, std::string& err)> is_valid_fn_;
|
||||
|
||||
public:
|
||||
void
|
||||
Init() override;
|
||||
|
||||
void
|
||||
Set(const std::string& value, bool update) override;
|
||||
|
||||
std::string
|
||||
Get() override;
|
||||
};
|
||||
|
||||
/* create config with {is_valid} function */
|
||||
|
||||
#define CreateBoolValue(name, modifiable, config_addr, default, is_valid) \
|
||||
std::make_shared<BoolValue>(name, nullptr, modifiable, config_addr, (default), is_valid)
|
||||
|
||||
#define CreateStringValue(name, modifiable, config_addr, default, is_valid) \
|
||||
std::make_shared<StringValue>(name, nullptr, modifiable, config_addr, (default), is_valid)
|
||||
|
||||
#define CreateEnumValue(name, modifiable, enumd, config_addr, default, is_valid) \
|
||||
std::make_shared<EnumValue>(name, nullptr, modifiable, enumd, config_addr, (default), is_valid)
|
||||
|
||||
#define CreateIntegerValue(name, modifiable, lower_bound, upper_bound, config_addr, default, is_valid) \
|
||||
std::make_shared<IntegerValue>(name, nullptr, modifiable, lower_bound, upper_bound, config_addr, (default), \
|
||||
is_valid)
|
||||
|
||||
#define CreateFloatingValue(name, modifiable, lower_bound, upper_bound, config_addr, default, is_valid) \
|
||||
std::make_shared<FloatingValue>(name, nullptr, modifiable, lower_bound, upper_bound, config_addr, (default), \
|
||||
is_valid)
|
||||
|
||||
#define CreateSizeValue(name, modifiable, lower_bound, upper_bound, config_addr, default, is_valid) \
|
||||
std::make_shared<SizeValue>(name, nullptr, modifiable, lower_bound, upper_bound, config_addr, (default), is_valid)
|
||||
|
||||
#define CreateTimeValue(name, modifiable, lower_bound, upper_bound, config_addr, default, is_valid) \
|
||||
std::make_shared<TimeValue>(name, nullptr, modifiable, lower_bound, upper_bound, config_addr, (default), is_valid)
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,387 +0,0 @@
|
||||
// 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 <cstring>
|
||||
#include <functional>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
#define _MODIFIABLE (true)
|
||||
#define _IMMUTABLE (false)
|
||||
|
||||
template <typename T>
|
||||
class Utils {
|
||||
public:
|
||||
bool
|
||||
validate_fn(const T& value, std::string& err) {
|
||||
validate_value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
T validate_value;
|
||||
};
|
||||
|
||||
/* ValidBoolValueTest */
|
||||
class ValidBoolValueTest : public testing::Test, public Utils<bool> {
|
||||
protected:
|
||||
};
|
||||
|
||||
TEST_F(ValidBoolValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidBoolValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, false, validate);
|
||||
ASSERT_EQ(bool_config->modifiable_, true);
|
||||
|
||||
bool_config->Init();
|
||||
ASSERT_EQ(bool_value(), false);
|
||||
ASSERT_EQ(bool_config->Get(), "false");
|
||||
|
||||
{
|
||||
// now `bool_value` is `false`, calling Set(update=false) to set it to `true`
|
||||
validate_value = false;
|
||||
|
||||
EXPECT_NO_THROW(bool_config->Set("true", false));
|
||||
|
||||
EXPECT_EQ(bool_value(), true);
|
||||
EXPECT_EQ(bool_config->Get(), "true");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, true);
|
||||
}
|
||||
|
||||
{
|
||||
// now `bool_value` is `true`, calling Set(update=true) to set it to `false`
|
||||
validate_value = true;
|
||||
|
||||
EXPECT_NO_THROW(bool_config->Set("false", true));
|
||||
|
||||
EXPECT_EQ(bool_value(), false);
|
||||
EXPECT_EQ(bool_config->Get(), "false");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* ValidStringValueTest */
|
||||
class ValidStringValueTest : public testing::Test, public Utils<std::string> {
|
||||
protected:
|
||||
};
|
||||
|
||||
TEST_F(ValidStringValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidStringValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", validate);
|
||||
ASSERT_EQ(string_config->modifiable_, true);
|
||||
|
||||
string_config->Init();
|
||||
ASSERT_EQ(string_value(), "Magic");
|
||||
ASSERT_EQ(string_config->Get(), "Magic");
|
||||
|
||||
{
|
||||
// now `string_value` is `Magic`, calling Set(update=false) to set it to `cigaM`
|
||||
validate_value = "";
|
||||
|
||||
EXPECT_NO_THROW(string_config->Set("cigaM", false));
|
||||
|
||||
EXPECT_EQ(string_value(), "cigaM");
|
||||
EXPECT_EQ(string_config->Get(), "cigaM");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, "cigaM");
|
||||
}
|
||||
|
||||
{
|
||||
// now `string_value` is `cigaM`, calling Set(update=true) to set it to `Check`
|
||||
validate_value = "";
|
||||
|
||||
EXPECT_NO_THROW(string_config->Set("Check", true));
|
||||
|
||||
EXPECT_EQ(string_value(), "Check");
|
||||
EXPECT_EQ(string_config->Get(), "Check");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, "Check");
|
||||
}
|
||||
}
|
||||
|
||||
/* ValidIntegerValueTest */
|
||||
class ValidIntegerValueTest : public testing::Test, public Utils<int64_t> {
|
||||
protected:
|
||||
};
|
||||
|
||||
TEST_F(ValidIntegerValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidIntegerValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", _MODIFIABLE, -100, 100, integer_value, 42, validate);
|
||||
ASSERT_EQ(integer_config->modifiable_, true);
|
||||
|
||||
integer_config->Init();
|
||||
ASSERT_EQ(integer_value(), 42);
|
||||
ASSERT_EQ(integer_config->Get(), "42");
|
||||
|
||||
{
|
||||
// now `integer_value` is `42`, calling Set(update=false) to set it to `24`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(integer_config->Set("24", false));
|
||||
|
||||
EXPECT_EQ(integer_value(), 24);
|
||||
EXPECT_EQ(integer_config->Get(), "24");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, 24);
|
||||
}
|
||||
|
||||
{
|
||||
// now `integer_value` is `24`, calling Set(update=true) to set it to `36`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(integer_config->Set("36", true));
|
||||
|
||||
EXPECT_EQ(integer_value(), 36);
|
||||
EXPECT_EQ(integer_config->Get(), "36");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, 36);
|
||||
}
|
||||
}
|
||||
|
||||
/* ValidFloatingValueTest */
|
||||
class ValidFloatingValueTest : public testing::Test, public Utils<double> {
|
||||
protected:
|
||||
};
|
||||
|
||||
TEST_F(ValidFloatingValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidFloatingValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", _MODIFIABLE, -10.0, 10.0, floating_value, 3.14, validate);
|
||||
ASSERT_EQ(floating_config->modifiable_, true);
|
||||
|
||||
floating_config->Init();
|
||||
ASSERT_FLOAT_EQ(floating_value(), 3.14);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 3.14);
|
||||
|
||||
{
|
||||
// now `floating_value` is `3.14`, calling Set(update=false) to set it to `6.22`
|
||||
validate_value = 0.0;
|
||||
|
||||
EXPECT_NO_THROW(floating_config->Set("6.22", false));
|
||||
|
||||
ASSERT_FLOAT_EQ(floating_value(), 6.22);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 6.22);
|
||||
|
||||
// expect change
|
||||
ASSERT_FLOAT_EQ(validate_value, 6.22);
|
||||
}
|
||||
|
||||
{
|
||||
// now `integer_value` is `6.22`, calling Set(update=true) to set it to `-3.14`
|
||||
validate_value = 0.0;
|
||||
|
||||
EXPECT_NO_THROW(floating_config->Set("-3.14", true));
|
||||
|
||||
ASSERT_FLOAT_EQ(floating_value(), -3.14);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), -3.14);
|
||||
|
||||
// expect change
|
||||
ASSERT_FLOAT_EQ(validate_value, -3.14);
|
||||
}
|
||||
}
|
||||
|
||||
/* ValidEnumValueTest */
|
||||
class ValidEnumValueTest : public testing::Test, public Utils<int64_t> {
|
||||
protected:
|
||||
};
|
||||
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::validate_value = 0;
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::new_value = 0;
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::prev_value = 0;
|
||||
|
||||
TEST_F(ValidEnumValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidEnumValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 1, validate);
|
||||
ASSERT_EQ(enum_config->modifiable_, true);
|
||||
|
||||
enum_config->Init();
|
||||
ASSERT_EQ(enum_value(), 1);
|
||||
ASSERT_EQ(enum_config->Get(), "a");
|
||||
|
||||
{
|
||||
// now `enum_value` is `a`, calling Set(update=false) to set it to `b`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(enum_config->Set("b", false));
|
||||
|
||||
ASSERT_EQ(enum_value(), 2);
|
||||
ASSERT_EQ(enum_config->Get(), "b");
|
||||
|
||||
// expect change
|
||||
ASSERT_EQ(validate_value, 2);
|
||||
}
|
||||
|
||||
{
|
||||
// now `enum_value` is `b`, calling Set(update=true) to set it to `c`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(enum_config->Set("c", true));
|
||||
|
||||
ASSERT_EQ(enum_value(), 3);
|
||||
ASSERT_EQ(enum_config->Get(), "c");
|
||||
|
||||
// expect change
|
||||
ASSERT_EQ(validate_value, 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* ValidSizeValueTest */
|
||||
class ValidSizeValueTest : public testing::Test, public Utils<int64_t> {
|
||||
protected:
|
||||
};
|
||||
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::validate_value = 0;
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::new_value = 0;
|
||||
// template <>
|
||||
// int64_t Utils<int64_t>::prev_value = 0;
|
||||
|
||||
TEST_F(ValidSizeValueTest, init_load_update_get_test) {
|
||||
auto validate = std::bind(&ValidSizeValueTest::validate_fn, this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", _MODIFIABLE, 0, 1024 * 1024, size_value, 1024, validate);
|
||||
ASSERT_EQ(size_config->modifiable_, true);
|
||||
|
||||
size_config->Init();
|
||||
ASSERT_EQ(size_value(), 1024);
|
||||
ASSERT_EQ(size_config->Get(), "1KB");
|
||||
|
||||
{
|
||||
// now `size_value` is `1024`, calling Set(update=false) to set it to `4096`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(size_config->Set("4096", false));
|
||||
|
||||
EXPECT_EQ(size_value(), 4096);
|
||||
EXPECT_EQ(size_config->Get(), "4KB");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, 4096);
|
||||
}
|
||||
|
||||
{
|
||||
// now `size_value` is `4096`, calling Set(update=true) to set it to `256kb`
|
||||
validate_value = 0;
|
||||
|
||||
EXPECT_NO_THROW(size_config->Set("256kb", true));
|
||||
|
||||
EXPECT_EQ(size_value(), 256 * 1024);
|
||||
EXPECT_EQ(size_config->Get(), "256KB");
|
||||
|
||||
// expect change
|
||||
EXPECT_EQ(validate_value, 262144);
|
||||
}
|
||||
}
|
||||
|
||||
class ValidTest : public testing::Test {
|
||||
protected:
|
||||
valueEnum family{
|
||||
{"ipv4", 1},
|
||||
{"ipv6", 2},
|
||||
};
|
||||
|
||||
struct Server {
|
||||
Value<bool> running;
|
||||
Value<std::string> hostname;
|
||||
Value<int64_t> family;
|
||||
Value<int64_t> port;
|
||||
Value<double> uptime;
|
||||
};
|
||||
|
||||
Server server;
|
||||
|
||||
protected:
|
||||
void
|
||||
SetUp() override {
|
||||
config_list = {
|
||||
CreateBoolValue("running", true, server.running, true, nullptr),
|
||||
CreateStringValue("hostname", true, server.hostname, "Magic", nullptr),
|
||||
CreateEnumValue("socket_family", false, &family, server.family, 2, nullptr),
|
||||
CreateIntegerValue("port", true, 1024, 65535, server.port, 19530, nullptr),
|
||||
CreateFloatingValue("uptime", true, 0, 9999.0, server.uptime, 0, nullptr),
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
TearDown() override {
|
||||
}
|
||||
|
||||
protected:
|
||||
void
|
||||
Init() {
|
||||
for (auto& config : config_list) {
|
||||
config->Init();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Load() {
|
||||
std::unordered_map<std::string, std::string> config_file{
|
||||
{"running", "false"},
|
||||
};
|
||||
|
||||
for (auto& c : config_file) Set(c.first, c.second, false);
|
||||
}
|
||||
|
||||
void
|
||||
Set(const std::string& name, const std::string& value, bool update = true) {
|
||||
for (auto& config : config_list) {
|
||||
if (std::strcmp(name.c_str(), config->name_) == 0) {
|
||||
config->Set(value, update);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw "Config " + name + " not found.";
|
||||
}
|
||||
|
||||
std::string
|
||||
Get(const std::string& name) {
|
||||
for (auto& config : config_list) {
|
||||
if (std::strcmp(name.c_str(), config->name_) == 0) {
|
||||
return config->Get();
|
||||
}
|
||||
}
|
||||
throw "Config " + name + " not found.";
|
||||
}
|
||||
|
||||
std::vector<BaseValuePtr> config_list;
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,633 +0,0 @@
|
||||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "value/config/ServerConfig.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
#define _MODIFIABLE (true)
|
||||
#define _IMMUTABLE (false)
|
||||
|
||||
template <typename T>
|
||||
class Utils {
|
||||
public:
|
||||
static bool
|
||||
valid_check_failure(const T& value, std::string& err) {
|
||||
err = "Value is invalid.";
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
valid_check_raise_string(const T& value, std::string& err) {
|
||||
throw "string exception";
|
||||
}
|
||||
|
||||
static bool
|
||||
valid_check_raise_exception(const T& value, std::string& err) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
};
|
||||
|
||||
/* BoolValueTest */
|
||||
class BoolValueTest : public testing::Test, public Utils<bool> {};
|
||||
|
||||
TEST_F(BoolValueTest, init_twice_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
bool_config->Init();
|
||||
bool_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, non_init_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, nullptr);
|
||||
ASSERT_DEATH(bool_config->Set("false", true), "uninitialized");
|
||||
ASSERT_DEATH(bool_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, immutable_update_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _IMMUTABLE, bool_value, true, nullptr);
|
||||
bool_config->Init();
|
||||
ASSERT_EQ(bool_value(), true);
|
||||
|
||||
EXPECT_THROW(bool_config->Set("false", true), Immutable);
|
||||
ASSERT_EQ(bool_value(), true);
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, set_invalid_value_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, nullptr);
|
||||
bool_config->Init();
|
||||
|
||||
EXPECT_THROW(bool_config->Set(" false", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("false ", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("afalse", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("falsee", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("abcdefg", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("123456", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
|
||||
EXPECT_THROW(bool_config->Set("", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, valid_check_fail_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, valid_check_failure);
|
||||
bool_config->Init();
|
||||
|
||||
EXPECT_THROW(bool_config->Set("123456", true), Invalid);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, string_exception_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, valid_check_raise_string);
|
||||
bool_config->Init();
|
||||
|
||||
EXPECT_THROW(bool_config->Set("false", true), Unexpected);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
}
|
||||
|
||||
TEST_F(BoolValueTest, standard_exception_test) {
|
||||
Value<bool> bool_value;
|
||||
auto bool_config = CreateBoolValue("b", _MODIFIABLE, bool_value, true, valid_check_raise_exception);
|
||||
bool_config->Init();
|
||||
|
||||
EXPECT_THROW(bool_config->Set("false", true), Unexpected);
|
||||
ASSERT_EQ(bool_config->Get(), "true");
|
||||
}
|
||||
|
||||
/* StringValueTest */
|
||||
class StringValueTest : public testing::Test, public Utils<std::string> {};
|
||||
|
||||
TEST_F(StringValueTest, init_twice_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
string_config->Init();
|
||||
string_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, non_init_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", nullptr);
|
||||
ASSERT_DEATH(string_config->Set("value", true), "uninitialized");
|
||||
ASSERT_DEATH(string_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, immutable_update_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _IMMUTABLE, string_value, "Magic", nullptr);
|
||||
string_config->Init();
|
||||
ASSERT_EQ(string_value(), "Magic");
|
||||
|
||||
EXPECT_THROW(string_config->Set("cigaM", true), Immutable);
|
||||
ASSERT_EQ(string_value(), "Magic");
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, valid_check_fail_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", valid_check_failure);
|
||||
string_config->Init();
|
||||
|
||||
EXPECT_THROW(string_config->Set("123456", true), Invalid);
|
||||
ASSERT_EQ(string_config->Get(), "Magic");
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, string_exception_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", valid_check_raise_string);
|
||||
string_config->Init();
|
||||
|
||||
EXPECT_THROW(string_config->Set("any", true), Unexpected);
|
||||
ASSERT_EQ(string_config->Get(), "Magic");
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, standard_exception_test) {
|
||||
Value<std::string> string_value;
|
||||
auto string_config = CreateStringValue("s", _MODIFIABLE, string_value, "Magic", valid_check_raise_exception);
|
||||
string_config->Init();
|
||||
|
||||
EXPECT_THROW(string_config->Set("any", true), Unexpected);
|
||||
ASSERT_EQ(string_config->Get(), "Magic");
|
||||
}
|
||||
|
||||
/* IntegerValueTest */
|
||||
class IntegerValueTest : public testing::Test, public Utils<int64_t> {};
|
||||
|
||||
TEST_F(IntegerValueTest, init_twice_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
integer_config->Init();
|
||||
integer_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, non_init_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, nullptr);
|
||||
ASSERT_DEATH(integer_config->Set("42", true), "uninitialized");
|
||||
ASSERT_DEATH(integer_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, immutable_update_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", _IMMUTABLE, 1024, 65535, integer_value, 19530, nullptr);
|
||||
integer_config->Init();
|
||||
ASSERT_EQ(integer_value(), 19530);
|
||||
|
||||
EXPECT_THROW(integer_config->Set("2048", true), Immutable);
|
||||
ASSERT_EQ(integer_value(), 19530);
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, set_invalid_value_test) {
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, valid_check_fail_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, valid_check_failure);
|
||||
integer_config->Init();
|
||||
EXPECT_THROW(integer_config->Set("2048", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "19530");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, string_exception_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, valid_check_raise_string);
|
||||
integer_config->Init();
|
||||
|
||||
EXPECT_THROW(integer_config->Set("2048", true), Unexpected);
|
||||
ASSERT_EQ(integer_config->Get(), "19530");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, standard_exception_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, valid_check_raise_exception);
|
||||
integer_config->Init();
|
||||
|
||||
EXPECT_THROW(integer_config->Set("2048", true), Unexpected);
|
||||
ASSERT_EQ(integer_config->Get(), "19530");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, out_of_range_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 1024, 65535, integer_value, 19530, nullptr);
|
||||
integer_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("1023", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(integer_config->Get(), "19530");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("65536", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(integer_config->Get(), "19530");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, invalid_bound_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 100, 0, integer_value, 50, nullptr);
|
||||
integer_config->Init();
|
||||
|
||||
EXPECT_THROW(integer_config->Set("30", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
TEST_F(IntegerValueTest, invalid_format_test) {
|
||||
Value<int64_t> integer_value;
|
||||
auto integer_config = CreateIntegerValue("i", true, 0, 100, integer_value, 50, nullptr);
|
||||
integer_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("3-0", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("30-", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("+30", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("a30", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("30a", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(integer_config->Set("3a0", true), Invalid);
|
||||
ASSERT_EQ(integer_config->Get(), "50");
|
||||
}
|
||||
}
|
||||
|
||||
/* FloatingValueTest */
|
||||
class FloatingValueTest : public testing::Test, public Utils<double> {};
|
||||
|
||||
TEST_F(FloatingValueTest, init_twice_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
floating_config->Init();
|
||||
floating_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, non_init_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, nullptr);
|
||||
ASSERT_DEATH(floating_config->Set("3.14", true), "uninitialized");
|
||||
ASSERT_DEATH(floating_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, immutable_update_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", _IMMUTABLE, 1.0, 9.9, floating_value, 4.5, nullptr);
|
||||
floating_config->Init();
|
||||
ASSERT_FLOAT_EQ(floating_value(), 4.5);
|
||||
|
||||
EXPECT_THROW(floating_config->Set("1.23", true), Immutable);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, set_invalid_value_test) {
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, valid_check_fail_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, valid_check_failure);
|
||||
floating_config->Init();
|
||||
|
||||
EXPECT_THROW(floating_config->Set("1.23", true), Invalid);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, string_exception_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, valid_check_raise_string);
|
||||
floating_config->Init();
|
||||
|
||||
EXPECT_THROW(floating_config->Set("1.23", true), Unexpected);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, standard_exception_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, valid_check_raise_exception);
|
||||
floating_config->Init();
|
||||
|
||||
EXPECT_THROW(floating_config->Set("1.23", true), Unexpected);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, out_of_range_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 9.9, floating_value, 4.5, valid_check_raise_exception);
|
||||
floating_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(floating_config->Set("0.99", true), OutOfRange<double>);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(floating_config->Set("10.00", true), OutOfRange<double>);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, invalid_bound_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 9.9, 1.0, floating_value, 4.5, valid_check_raise_exception);
|
||||
floating_config->Init();
|
||||
|
||||
EXPECT_THROW(floating_config->Set("6.0", true), OutOfRange<double>);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
TEST_F(FloatingValueTest, DISABLED_invalid_format_test) {
|
||||
Value<double> floating_value;
|
||||
auto floating_config = CreateFloatingValue("f", true, 1.0, 100.0, floating_value, 4.5, nullptr);
|
||||
floating_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(floating_config->Set("6.0.1", true), Invalid);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(floating_config->Set("6a0", true), Invalid);
|
||||
ASSERT_FLOAT_EQ(std::stof(floating_config->Get()), 4.5);
|
||||
}
|
||||
}
|
||||
|
||||
/* EnumValueTest */
|
||||
class EnumValueTest : public testing::Test, public Utils<int64_t> {};
|
||||
|
||||
TEST_F(EnumValueTest, init_twice_test) {
|
||||
valueEnum testEnum{
|
||||
{"e", 1},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 2, nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
enum_config->Init();
|
||||
enum_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, non_init_test) {
|
||||
valueEnum testEnum{
|
||||
{"e", 1},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 2, nullptr);
|
||||
ASSERT_DEATH(enum_config->Set("e", true), "uninitialized");
|
||||
ASSERT_DEATH(enum_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, immutable_update_test) {
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _IMMUTABLE, &testEnum, enum_value, 1, nullptr);
|
||||
enum_config->Init();
|
||||
ASSERT_EQ(enum_value(), 1);
|
||||
|
||||
EXPECT_THROW(enum_config->Set("b", true), Immutable);
|
||||
ASSERT_EQ(enum_value(), 1);
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, set_invalid_value_check) {
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 1, nullptr);
|
||||
enum_config->Init();
|
||||
|
||||
EXPECT_THROW(enum_config->Set("b", true), EnumValueNotFound);
|
||||
ASSERT_EQ(enum_config->Get(), "a");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, empty_enum_test) {
|
||||
valueEnum testEnum{};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 2, nullptr);
|
||||
ASSERT_DEATH(enum_config->Init(), "empty");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, valid_check_fail_test) {
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 1, valid_check_failure);
|
||||
enum_config->Init();
|
||||
|
||||
EXPECT_THROW(enum_config->Set("b", true), Invalid);
|
||||
ASSERT_EQ(enum_config->Get(), "a");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, string_exception_test) {
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 1, valid_check_raise_string);
|
||||
enum_config->Init();
|
||||
|
||||
EXPECT_THROW(enum_config->Set("b", true), Unexpected);
|
||||
ASSERT_EQ(enum_config->Get(), "a");
|
||||
}
|
||||
|
||||
TEST_F(EnumValueTest, standard_exception_test) {
|
||||
valueEnum testEnum{
|
||||
{"a", 1},
|
||||
{"b", 2},
|
||||
{"c", 3},
|
||||
};
|
||||
Value<int64_t> enum_value;
|
||||
auto enum_config = CreateEnumValue("e", _MODIFIABLE, &testEnum, enum_value, 1, valid_check_raise_exception);
|
||||
enum_config->Init();
|
||||
|
||||
EXPECT_THROW(enum_config->Set("b", true), Unexpected);
|
||||
ASSERT_EQ(enum_config->Get(), "a");
|
||||
}
|
||||
|
||||
/* SizeValueTest */
|
||||
class SizeValueTest : public testing::Test, public Utils<int64_t> {};
|
||||
|
||||
TEST_F(SizeValueTest, init_twice_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
ASSERT_DEATH(
|
||||
{
|
||||
size_config->Init();
|
||||
size_config->Init();
|
||||
},
|
||||
"initialized");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, non_init_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
ASSERT_DEATH(size_config->Set("3000", true), "uninitialized");
|
||||
ASSERT_DEATH(size_config->Get(), "uninitialized");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, immutable_update_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", _IMMUTABLE, 1024, 4096, size_value, 2048, nullptr);
|
||||
size_config->Init();
|
||||
ASSERT_EQ(size_value(), 2048);
|
||||
|
||||
EXPECT_THROW(size_config->Set("3000", true), Immutable);
|
||||
ASSERT_EQ(size_value(), 2048);
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, set_invalid_value_test) {
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, valid_check_fail_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, valid_check_failure);
|
||||
size_config->Init();
|
||||
|
||||
EXPECT_THROW(size_config->Set("3000", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, string_exception_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, valid_check_raise_string);
|
||||
size_config->Init();
|
||||
|
||||
EXPECT_THROW(size_config->Set("3000", true), Unexpected);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, standard_exception_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, valid_check_raise_exception);
|
||||
size_config->Init();
|
||||
|
||||
EXPECT_THROW(size_config->Set("3000", true), Unexpected);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, out_of_range_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
size_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(size_config->Set("1023", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(size_config->Set("4097", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, negative_integer_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
size_config->Init();
|
||||
EXPECT_THROW(size_config->Set("-3KB", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, invalid_bound_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 100, 0, size_value, 50, nullptr);
|
||||
size_config->Init();
|
||||
|
||||
EXPECT_THROW(size_config->Set("30", true), OutOfRange<int64_t>);
|
||||
ASSERT_EQ(size_config->Get(), "50");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, invalid_unit_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
size_config->Init();
|
||||
|
||||
EXPECT_THROW(size_config->Set("1 TB", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
TEST_F(SizeValueTest, invalid_format_test) {
|
||||
Value<int64_t> size_value;
|
||||
auto size_config = CreateSizeValue("i", true, 1024, 4096, size_value, 2048, nullptr);
|
||||
size_config->Init();
|
||||
|
||||
{
|
||||
EXPECT_THROW(size_config->Set("a10GB", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(size_config->Set("200*0", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_THROW(size_config->Set("10AB", true), Invalid);
|
||||
ASSERT_EQ(size_config->Get(), "2KB");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,399 +0,0 @@
|
||||
// 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 <sys/sysinfo.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "value/config/ServerConfig.h"
|
||||
|
||||
/* to find modifiable settings fast */
|
||||
#define _MODIFIABLE (true)
|
||||
#define _IMMUTABLE (false)
|
||||
const int64_t MB = (1024ll * 1024);
|
||||
const int64_t GB = (1024ll * 1024 * 1024);
|
||||
const int64_t HOURS = (3600ll);
|
||||
const int64_t DAYS = (HOURS * 24);
|
||||
|
||||
namespace milvus {
|
||||
|
||||
bool
|
||||
is_nodeid_valid(const std::string& val, std::string& err) {
|
||||
// lambda, check if it's [0-9a-zA-Z_-]
|
||||
auto is_valid = [](char ch) {
|
||||
if (isalnum(ch) || ch == '_' || ch == '-') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (auto& ch : val) {
|
||||
if (not is_valid(ch)) {
|
||||
err = "Invalid nodeid: " + val + ", supported char: [0-9a-zA-Z_-]";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
is_timezone_valid(const std::string& val, std::string& err) {
|
||||
auto plus_count = std::count(val.begin(), val.end(), '+');
|
||||
auto sub_count = std::count(val.begin(), val.end(), '-');
|
||||
if (plus_count > 1 or sub_count > 1) {
|
||||
err = "Invalid timezone: " + val;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
is_cachesize_valid(int64_t size, std::string& err) {
|
||||
try {
|
||||
// Get max docker memory size
|
||||
int64_t limit_in_bytes;
|
||||
std::ifstream file("/sys/fs/cgroup/memory/memory.limit_in_bytes");
|
||||
if (file.fail()) {
|
||||
throw std::runtime_error("Failed to read /sys/fs/cgroup/memory/memory.limit_in_bytes.");
|
||||
}
|
||||
file >> limit_in_bytes;
|
||||
|
||||
// Get System info
|
||||
int64_t total_mem = 0;
|
||||
struct sysinfo info;
|
||||
int ret = sysinfo(&info);
|
||||
if (ret != 0) {
|
||||
throw std::runtime_error("Get sysinfo failed.");
|
||||
}
|
||||
total_mem = info.totalram;
|
||||
|
||||
if (limit_in_bytes < total_mem && size > limit_in_bytes) {
|
||||
std::string msg =
|
||||
"Invalid cpu cache size: " + std::to_string(size) +
|
||||
". cache.cache_size exceeds system cgroup memory size: " + std::to_string(limit_in_bytes) + "." +
|
||||
"Consider increase docker memory limit.";
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
return true;
|
||||
} catch (std::exception& ex) {
|
||||
err = "Check cache.cache_size valid failed, reason: " + std::string(ex.what());
|
||||
return false;
|
||||
} catch (...) {
|
||||
err = "Check cache.cache_size valid failed, unknown reason.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define Bool_(name, modifiable, default, is_valid) \
|
||||
{ #name, CreateBoolValue(#name, modifiable, config.name, default, is_valid) }
|
||||
#define String_(name, modifiable, default, is_valid) \
|
||||
{ #name, CreateStringValue(#name, modifiable, config.name, default, is_valid) }
|
||||
#define Enum_(name, modifiable, enumd, default, is_valid) \
|
||||
{ #name, CreateEnumValue(#name, modifiable, enumd, config.name, default, is_valid) }
|
||||
#define Integer_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateIntegerValue(#name, modifiable, lower_bound, upper_bound, config.name, default, is_valid) }
|
||||
#define Floating_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateFloatingValue(#name, modifiable, lower_bound, upper_bound, config.name, default, is_valid) }
|
||||
#define Size_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateSizeValue(#name, modifiable, lower_bound, upper_bound, config.name, default, is_valid) }
|
||||
#define Time_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateTimeValue(#name, modifiable, lower_bound, upper_bound, config.name, default, is_valid) }
|
||||
|
||||
#define Bool(name, default) Bool_(name, true, default, nullptr)
|
||||
#define String(name, default) String_(name, true, default, nullptr)
|
||||
#define Enum(name, enumd, default) Enum_(name, true, enumd, default, nullptr)
|
||||
#define Integer(name, lower_bound, upper_bound, default) \
|
||||
Integer_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
#define Floating(name, lower_bound, upper_bound, default) \
|
||||
Floating_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
#define Size(name, lower_bound, upper_bound, default) Size_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
#define Time(name, lower_bound, upper_bound, default) Time_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
|
||||
std::unordered_map<std::string, BaseValuePtr>
|
||||
InitConfig() {
|
||||
return std::unordered_map<std::string, BaseValuePtr>{
|
||||
/* version */
|
||||
String(version, "unknown"),
|
||||
|
||||
/* cluster */
|
||||
Bool(cluster.enable, false),
|
||||
Enum(cluster.role, &ClusterRoleMap, ClusterRole::RW),
|
||||
String_(cluster.node_id, _MODIFIABLE, "master", is_nodeid_valid),
|
||||
|
||||
/* general */
|
||||
String_(general.timezone, _MODIFIABLE, "UTC+8", is_timezone_valid),
|
||||
String(general.meta_uri, "sqlite://:@:/"),
|
||||
Integer(general.stale_snapshots_count, 0, 100, 0),
|
||||
Integer(general.stale_snapshots_duration, 0, std::numeric_limits<int64_t>::max(), 10),
|
||||
|
||||
/* network */
|
||||
String(network.bind.address, "0.0.0.0"),
|
||||
Integer(network.bind.port, 1025, 65534, 19530),
|
||||
Bool(network.http.enable, true),
|
||||
Integer(network.http.port, 1025, 65534, 19121),
|
||||
|
||||
/* storage */
|
||||
String(storage.path, "/var/lib/milvus"),
|
||||
Integer(storage.auto_flush_interval, 0, std::numeric_limits<int64_t>::max(), 1),
|
||||
|
||||
/* wal */
|
||||
Bool(wal.enable, true),
|
||||
Bool(wal.sync_mode, false),
|
||||
Bool(wal.recovery_error_ignore, false),
|
||||
Size(wal.buffer_size, 64 * MB, 4096 * MB, 256 * MB),
|
||||
String(wal.path, "/var/lib/milvus/wal"),
|
||||
|
||||
/* cache */
|
||||
Size_(cache.cache_size, _MODIFIABLE, 0, std::numeric_limits<int64_t>::max(), 4 * GB, is_cachesize_valid),
|
||||
Floating(cache.cpu_cache_threshold, 0.0, 1.0, 0.7),
|
||||
Size(cache.insert_buffer_size, 0, std::numeric_limits<int64_t>::max(), 1 * GB),
|
||||
Bool(cache.cache_insert_data, false),
|
||||
String(cache.preload_collection, ""),
|
||||
Size(cache.max_concurrent_insert_request_size, 256 * MB, std::numeric_limits<int64_t>::max(), 2 * GB),
|
||||
|
||||
/* gpu */
|
||||
Bool(gpu.enable, false),
|
||||
Size(gpu.cache_size, 0, std::numeric_limits<int64_t>::max(), 1 * GB),
|
||||
Floating(gpu.cache_threshold, 0.0, 1.0, 0.7),
|
||||
Integer(gpu.gpu_search_threshold, 0, std::numeric_limits<int64_t>::max(), 1000),
|
||||
String(gpu.search_devices, "gpu0"),
|
||||
String(gpu.build_index_devices, "gpu0"),
|
||||
|
||||
/* log */
|
||||
Bool(logs.trace.enable, true),
|
||||
String(logs.path, "/var/lib/milvus/logs"),
|
||||
Size(logs.max_log_file_size, 512 * MB, 4096 * MB, 1024 * MB),
|
||||
Integer(logs.log_rotate_num, 0, 1024, 0),
|
||||
Bool(logs.log_to_stdout, false),
|
||||
Bool(logs.log_to_file, true),
|
||||
|
||||
String(log.min_messages, "warning"),
|
||||
Time(log.rotation_age, 0, 16384ll * HOURS, 24ll * HOURS),
|
||||
Size(log.rotation_size, 128 * MB, 8192 * MB, 1024 * MB),
|
||||
|
||||
/* tracing */
|
||||
String(tracing.json_config_path, ""),
|
||||
|
||||
/* invisible */
|
||||
/* engine */
|
||||
Integer(engine.max_partition_num, 1, std::numeric_limits<int64_t>::max(), 4096),
|
||||
Integer(engine.build_index_threshold, 0, std::numeric_limits<int64_t>::max(), 4096),
|
||||
Integer(engine.search_combine_nq, 0, std::numeric_limits<int64_t>::max(), 64),
|
||||
Integer(engine.use_blas_threshold, 0, std::numeric_limits<int64_t>::max(), 16385),
|
||||
Integer(engine.omp_thread_num, 0, std::numeric_limits<int64_t>::max(), 0),
|
||||
Enum(engine.clustering_type, &ClusteringMap, ClusteringType::K_MEANS),
|
||||
Enum(engine.simd_type, &SimdMap, SimdType::AUTO),
|
||||
Integer(engine.statistics_level, 0, 3, 1),
|
||||
|
||||
Bool(system.lock.enable, true),
|
||||
|
||||
Bool(transcript.enable, false),
|
||||
String(transcript.replay, ""),
|
||||
};
|
||||
}
|
||||
|
||||
const char* config_file_template = R"(
|
||||
|
||||
# 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.
|
||||
|
||||
version: @version@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Cluster Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# enable | If running with Mishards, set true, otherwise false. | Boolean | false |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# role | Milvus deployment role: rw / ro | Role | rw |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# node_id | Node ID, used in log message only. | String | master |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
cluster:
|
||||
enable: @cluster.enable@
|
||||
role: @cluster.role@
|
||||
node_id: @cluster.node_id@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# General Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# timezone | Use UTC-x or UTC+x to specify a time zone. | Timezone | UTC+8 |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# meta_uri | URI for metadata storage, using SQLite (for single server | URI | sqlite://:@:/ |
|
||||
# | Milvus) or MySQL (for distributed cluster Milvus). | | |
|
||||
# | Format: dialect://username:password@host:port/database | | |
|
||||
# | Keep 'dialect://:@:/', 'dialect' can be either 'sqlite' or | | |
|
||||
# | 'mysql', replace other texts with real values. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# stale_snapshots_count| Specify how many stale snapshots to be kept before GC. It | Integer | 0 |
|
||||
# | is ignored if deployed with cluster enabled | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# stale_snapshots_duration | | Integer | 10 |
|
||||
# | Specify how long the stale snapshots can be GC'ed. The unit| | |
|
||||
# | is second. It is only effective if deployed with cluster | | |
|
||||
# | enabled and cluster.role is rw | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
general:
|
||||
timezone: @general.timezone@
|
||||
meta_uri: @general.meta_uri@
|
||||
stale_snapshots_count: @general.stale_snapshots_count@
|
||||
stale_snapshots_duration: @general.stale_snapshots_duration@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Network Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# bind.address | IP address that Milvus server monitors. | IP | 0.0.0.0 |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# bind.port | Port that Milvus server monitors. Port range (1024, 65535) | Integer | 19530 |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# http.enable | Enable HTTP server or not. | Boolean | true |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# http.port | Port that Milvus HTTP server monitors. | Integer | 19121 |
|
||||
# | Port range (1024, 65535) | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
network:
|
||||
bind.address: @network.bind.address@
|
||||
bind.port: @network.bind.port@
|
||||
http.enable: @network.http.enable@
|
||||
http.port: @network.http.port@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Storage Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# path | Path used to save meta data, vector data and index data. | Path | /var/lib/milvus |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# auto_flush_interval | The interval, in seconds, at which Milvus automatically | Integer | 1 (s) |
|
||||
# | flushes data to disk. | | |
|
||||
# | 0 means disable the regular flush. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
storage:
|
||||
path: @storage.path@
|
||||
auto_flush_interval: @storage.auto_flush_interval@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# WAL Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# enable | Whether to enable write-ahead logging (WAL) in Milvus. | Boolean | true |
|
||||
# | If WAL is enabled, Milvus writes all data changes to log | | |
|
||||
# | files in advance before implementing data changes. WAL | | |
|
||||
# | ensures the atomicity and durability for Milvus operations.| | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# path | Location of WAL log files. | String | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
wal:
|
||||
enable: @wal.enable@
|
||||
path: @wal.path@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Cache Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# cache_size | The size of CPU memory used for caching data for faster | String | 4GB |
|
||||
# | query. The sum of 'cache_size' and 'insert_buffer_size' | | |
|
||||
# | must be less than system memory size. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# insert_buffer_size | Buffer size used for data insertion. | String | 1GB |
|
||||
# | The sum of 'insert_buffer_size' and 'cache_size' | | |
|
||||
# | must be less than system memory size. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# preload_collection | A comma-separated list of collection names that need to | StringList | |
|
||||
# | be pre-loaded when Milvus server starts up. | | |
|
||||
# | '*' means preload all existing tables (single-quote or | | |
|
||||
# | double-quote required). | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# max_concurrent_insert_request_size | | | |
|
||||
# | A size limit on the concurrent insert requests to process. | String | 2GB |
|
||||
# | Milvus can process insert requests from multiple clients | | |
|
||||
# | concurrently. This setting puts a cap on the memory | | |
|
||||
# | consumption during this process. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
cache:
|
||||
cache_size: @cache.cache_size@
|
||||
insert_buffer_size: @cache.insert_buffer_size@
|
||||
preload_collection: @cache.preload_collection@
|
||||
max_concurrent_insert_request_size: @cache.max_concurrent_insert_request_size@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# GPU Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# enable | Use GPU devices or not. | Boolean | false |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# cache_size | The size of GPU memory per card used for cache. | String | 1GB |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# gpu_search_threshold | A Milvus performance tuning parameter. This value will be | Integer | 1000 |
|
||||
# | compared with 'nq' to decide if the search computation will| | |
|
||||
# | be executed on GPUs only. | | |
|
||||
# | If nq >= gpu_search_threshold, the search computation will | | |
|
||||
# | be executed on GPUs only; | | |
|
||||
# | if nq < gpu_search_threshold, the search computation will | | |
|
||||
# | be executed on both CPUs and GPUs. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# search_devices | The list of GPU devices used for search computation. | DeviceList | gpu0 |
|
||||
# | Must be in format gpux. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# build_index_devices | The list of GPU devices used for index building. | DeviceList | gpu0 |
|
||||
# | Must be in format gpux. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
gpu:
|
||||
enable: @gpu.enable@
|
||||
cache_size: @gpu.cache_size@
|
||||
gpu_search_threshold: @gpu.gpu_search_threshold@
|
||||
search_devices: @gpu.search_devices@
|
||||
build_index_devices: @gpu.build_index_devices@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Logs Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# trace.enable | Whether to enable trace level logging in Milvus. | Boolean | true |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# path | Absolute path to the folder holding the log files. | String | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# max_log_file_size | The maximum size of each log file, size range | String | 1024MB |
|
||||
# | [512MB, 4096MB]. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# log_rotate_num | The maximum number of log files that Milvus keeps for each | Integer | 0 |
|
||||
# | logging level, num range [0, 1024], 0 means unlimited. | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# log_to_stdout | Whether logging to standard output. | Boolean | false |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# log_to_file | Whether logging to log files. | Boolean | true |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
logs:
|
||||
trace.enable: @logs.trace.enable@
|
||||
path: @logs.path@
|
||||
max_log_file_size: @logs.max_log_file_size@
|
||||
log_rotate_num: @logs.log_rotate_num@
|
||||
log_to_stdout: @logs.log_to_stdout@
|
||||
log_to_file: @logs.log_to_file@
|
||||
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# Log Config | Description | Type | Default |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# min_messages | Log level in Milvus. Must be one of debug, info, warning, | String | warning |
|
||||
# | error, fatal | | |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# rotation_age | When to generate new logfile. | Time | 24 hours |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
# rotation_size | When to generate new logfile. | Size | 1GB |
|
||||
#----------------------+------------------------------------------------------------+------------+-----------------+
|
||||
log:
|
||||
min_messages: @log.min_messages@
|
||||
rotation_age: @log.rotation_age@
|
||||
rotation_size: @log.rotation_size@
|
||||
|
||||
)";
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,185 +0,0 @@
|
||||
// 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 <yaml-cpp/yaml.h>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "value/config/ConfigMgr.h"
|
||||
|
||||
namespace {
|
||||
void
|
||||
Flatten(const YAML::Node& node, std::unordered_map<std::string, std::string>& target, const std::string& prefix) {
|
||||
for (auto& it : node) {
|
||||
auto key = prefix.empty() ? it.first.as<std::string>() : prefix + "." + it.first.as<std::string>();
|
||||
switch (it.second.Type()) {
|
||||
case YAML::NodeType::Null: {
|
||||
target[key] = "";
|
||||
break;
|
||||
}
|
||||
case YAML::NodeType::Scalar: {
|
||||
target[key] = it.second.as<std::string>();
|
||||
break;
|
||||
}
|
||||
case YAML::NodeType::Sequence: {
|
||||
std::string value;
|
||||
for (auto& sub : it.second) value += sub.as<std::string>() + ",";
|
||||
target[key] = value;
|
||||
break;
|
||||
}
|
||||
case YAML::NodeType::Map: {
|
||||
Flatten(it.second, target, key);
|
||||
break;
|
||||
}
|
||||
case YAML::NodeType::Undefined: {
|
||||
std::runtime_error("Undefined YAML Node is not supported in Flatten.");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // namespace
|
||||
|
||||
namespace milvus {
|
||||
|
||||
extern std::unordered_map<std::string, BaseValuePtr>
|
||||
InitConfig();
|
||||
|
||||
extern const char* config_file_template;
|
||||
|
||||
ConfigMgr ConfigMgr::instance;
|
||||
|
||||
ConfigMgr::ConfigMgr() : ValueMgr(InitConfig()) {
|
||||
effective_immediately_ = {
|
||||
"cache.cache_size",
|
||||
"gpu.cache_size",
|
||||
"gpu.gpu_search_threshold",
|
||||
"storage.auto_flush_interval",
|
||||
"engine.build_index_threshold",
|
||||
"engine.search_combine_nq",
|
||||
"engine.use_blas_threshold",
|
||||
"engine.omp_thread_num",
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ConfigMgr::LoadFile(const std::string& path) {
|
||||
try {
|
||||
/* load from milvus.yaml */
|
||||
auto yaml = YAML::LoadFile(path);
|
||||
|
||||
/* make it flattened */
|
||||
std::unordered_map<std::string, std::string> flattened;
|
||||
Flatten(yaml, flattened, "");
|
||||
|
||||
/* update config */
|
||||
for (auto& it : flattened) Set(it.first, it.second, false);
|
||||
|
||||
config_file_ = path;
|
||||
} catch (std::exception& ex) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigMgr::LoadMemory(const std::string& yaml_string) {
|
||||
try {
|
||||
auto yaml = YAML::Load(yaml_string);
|
||||
|
||||
/* make it flattened */
|
||||
std::unordered_map<std::string, std::string> flattened;
|
||||
Flatten(yaml, flattened, "");
|
||||
|
||||
/* update config */
|
||||
for (auto& it : flattened) Set(it.first, it.second, false);
|
||||
} catch (std::exception& ex) {
|
||||
throw;
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigMgr::Set(const std::string& name, const std::string& value, bool update) {
|
||||
/* Check if existed */
|
||||
if (config_list_.find(name) == config_list_.end()) {
|
||||
throw std::runtime_error("Config " + name + " not found.");
|
||||
}
|
||||
|
||||
auto old_value = config_list_.at(name)->Get();
|
||||
|
||||
try {
|
||||
/* Set value, throws ValueError only. */
|
||||
config_list_.at(name)->Set(value, update);
|
||||
|
||||
if (update) {
|
||||
/* Save file */
|
||||
Save();
|
||||
|
||||
/* Notify who observe this value */
|
||||
Notify(name);
|
||||
|
||||
/* Update flag */
|
||||
if (effective_immediately_.find(name) == effective_immediately_.end()) {
|
||||
require_restart_ |= true;
|
||||
}
|
||||
}
|
||||
} catch (ValueError& e) {
|
||||
/* Convert to std::runtime_error. */
|
||||
throw std::runtime_error(e.message());
|
||||
} catch (SaveValueError& e) {
|
||||
/* Save config failed, rollback and convert to std::runtime_error. */
|
||||
config_list_.at(name)->Set(old_value, false);
|
||||
throw std::runtime_error(e.message);
|
||||
} catch (...) {
|
||||
/* Unexpected exception, output config and value. */
|
||||
throw std::runtime_error("Unexpected exception happened when setting " + value + " to " + name + ".");
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
ConfigMgr::Get(const std::string& name) const {
|
||||
try {
|
||||
auto& config = config_list_.at(name);
|
||||
return config->Get();
|
||||
} catch (std::out_of_range& ex) {
|
||||
throw std::runtime_error("Config " + name + " not found.");
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Unexpected exception happened when getting config " + name + ".");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigMgr::Save() {
|
||||
if (config_file_.empty()) {
|
||||
throw SaveValueError("Cannot save config into empty path.");
|
||||
}
|
||||
|
||||
std::string file_content(config_file_template);
|
||||
for (auto& config_pair : config_list_) {
|
||||
auto placeholder = "@" + config_pair.first + "@";
|
||||
file_content = std::regex_replace(file_content, std::regex(placeholder), config_pair.second->Get());
|
||||
}
|
||||
|
||||
std::ofstream config_file(config_file_);
|
||||
config_file << file_content;
|
||||
config_file.close();
|
||||
|
||||
if (config_file.fail()) {
|
||||
throw SaveValueError("Cannot save config into file: " + config_file_ + ".");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,91 +0,0 @@
|
||||
// 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 <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "value/ValueMgr.h"
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
class ConfigObserver : public ValueObserver {
|
||||
public:
|
||||
void
|
||||
ValueUpdate(const std::string& name) override {
|
||||
ConfigUpdate(name);
|
||||
}
|
||||
|
||||
virtual void
|
||||
ConfigUpdate(const std::string& name) = 0;
|
||||
};
|
||||
|
||||
class ConfigMgr : public ValueMgr {
|
||||
public:
|
||||
static ConfigMgr&
|
||||
GetInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static ConfigMgr instance;
|
||||
|
||||
public:
|
||||
bool
|
||||
RequireRestart() {
|
||||
return require_restart_;
|
||||
}
|
||||
|
||||
public:
|
||||
ConfigMgr();
|
||||
|
||||
/* throws std::exception only */
|
||||
void
|
||||
LoadFile(const std::string& path);
|
||||
|
||||
/* for testing */
|
||||
/* throws std::exception only */
|
||||
void
|
||||
LoadMemory(const std::string& yaml_string);
|
||||
|
||||
/* throws std::exception only */
|
||||
void
|
||||
Set(const std::string& name, const std::string& value, bool update) override;
|
||||
|
||||
/* throws std::exception only */
|
||||
std::string
|
||||
Get(const std::string& name) const override;
|
||||
|
||||
private:
|
||||
struct SaveValueError : public std::exception {
|
||||
explicit SaveValueError(const std::string& msg) : message(msg) {
|
||||
}
|
||||
const std::string message;
|
||||
};
|
||||
|
||||
void
|
||||
Save();
|
||||
|
||||
private:
|
||||
const std::unordered_map<std::string, BaseValuePtr>& config_list_ = value_list_;
|
||||
std::string config_file_;
|
||||
bool require_restart_ = false;
|
||||
std::set<std::string> effective_immediately_;
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,60 +0,0 @@
|
||||
// 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 <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "value/config/ServerConfig.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
std::mutex config_mutex;
|
||||
|
||||
ServerConfig config;
|
||||
|
||||
std::vector<std::string>
|
||||
ParsePreloadCollection(const std::string& str) {
|
||||
std::stringstream ss(str);
|
||||
std::vector<std::string> collections;
|
||||
std::string collection;
|
||||
|
||||
while (std::getline(ss, collection, ',')) {
|
||||
collections.push_back(collection);
|
||||
}
|
||||
return collections;
|
||||
}
|
||||
|
||||
std::vector<int64_t>
|
||||
ParseGPUDevices(const std::string& str) {
|
||||
std::stringstream ss(str);
|
||||
std::vector<int64_t> devices;
|
||||
std::unordered_set<int64_t> device_set;
|
||||
std::string device;
|
||||
|
||||
while (std::getline(ss, device, ',')) {
|
||||
if (device.length() < 4) {
|
||||
/* Invalid format string */
|
||||
return {};
|
||||
}
|
||||
device_set.insert(std::stoll(device.substr(3)));
|
||||
}
|
||||
|
||||
devices.reserve(device_set.size());
|
||||
for (auto dev : device_set) {
|
||||
devices.push_back(dev);
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,172 +0,0 @@
|
||||
// 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 <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "value/Value.h"
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
enum ClusterRole {
|
||||
RW = 1,
|
||||
RO,
|
||||
};
|
||||
|
||||
const valueEnum ClusterRoleMap{
|
||||
{"rw", ClusterRole::RW},
|
||||
{"ro", ClusterRole::RO},
|
||||
};
|
||||
|
||||
enum SimdType {
|
||||
AUTO = 1,
|
||||
SSE4_2,
|
||||
AVX2,
|
||||
AVX512,
|
||||
};
|
||||
|
||||
const valueEnum SimdMap{
|
||||
{"auto", SimdType::AUTO},
|
||||
{"sse4_2", SimdType::SSE4_2},
|
||||
{"avx2", SimdType::AVX2},
|
||||
{"avx512", SimdType::AVX512},
|
||||
};
|
||||
|
||||
enum ClusteringType {
|
||||
K_MEANS = 1,
|
||||
K_MEANS_PLUS_PLUS,
|
||||
};
|
||||
|
||||
const valueEnum ClusteringMap{
|
||||
{"k-means", ClusteringType::K_MEANS},
|
||||
{"k-means++", ClusteringType::K_MEANS_PLUS_PLUS},
|
||||
};
|
||||
|
||||
struct ServerConfig {
|
||||
using String = Value<std::string>;
|
||||
using Bool = Value<bool>;
|
||||
using Integer = Value<int64_t>;
|
||||
using Floating = Value<double>;
|
||||
|
||||
String version;
|
||||
|
||||
struct Cluster {
|
||||
Bool enable;
|
||||
Integer role;
|
||||
String node_id;
|
||||
} cluster;
|
||||
|
||||
struct General {
|
||||
String timezone;
|
||||
String meta_uri;
|
||||
Integer stale_snapshots_count;
|
||||
Integer stale_snapshots_duration;
|
||||
} general;
|
||||
|
||||
struct Network {
|
||||
struct Bind {
|
||||
String address;
|
||||
Integer port;
|
||||
} bind;
|
||||
struct Http {
|
||||
Bool enable;
|
||||
Integer port;
|
||||
} http;
|
||||
} network;
|
||||
|
||||
struct Storage {
|
||||
String path;
|
||||
Integer auto_flush_interval;
|
||||
} storage;
|
||||
|
||||
struct Cache {
|
||||
Integer cache_size;
|
||||
Floating cpu_cache_threshold;
|
||||
Integer insert_buffer_size;
|
||||
Bool cache_insert_data;
|
||||
String preload_collection;
|
||||
Integer max_concurrent_insert_request_size;
|
||||
} cache;
|
||||
|
||||
struct Engine {
|
||||
Integer max_partition_num;
|
||||
Integer build_index_threshold;
|
||||
Integer search_combine_nq;
|
||||
Integer use_blas_threshold;
|
||||
Integer omp_thread_num;
|
||||
Integer clustering_type;
|
||||
Integer simd_type;
|
||||
Integer statistics_level;
|
||||
} engine;
|
||||
|
||||
struct GPU {
|
||||
Bool enable;
|
||||
Integer cache_size;
|
||||
Floating cache_threshold;
|
||||
Integer gpu_search_threshold;
|
||||
String search_devices;
|
||||
String build_index_devices;
|
||||
} gpu;
|
||||
|
||||
struct Tracing {
|
||||
String json_config_path;
|
||||
} tracing;
|
||||
|
||||
struct WAL {
|
||||
Bool enable;
|
||||
Bool sync_mode;
|
||||
Bool recovery_error_ignore;
|
||||
Integer buffer_size;
|
||||
String path;
|
||||
} wal;
|
||||
|
||||
struct Logs {
|
||||
struct Trace {
|
||||
Bool enable;
|
||||
} trace;
|
||||
String path;
|
||||
Integer max_log_file_size;
|
||||
Integer log_rotate_num;
|
||||
Bool log_to_stdout;
|
||||
Bool log_to_file;
|
||||
} logs;
|
||||
|
||||
struct Log {
|
||||
String min_messages;
|
||||
Integer rotation_age;
|
||||
Integer rotation_size;
|
||||
} log;
|
||||
|
||||
struct System {
|
||||
struct Lock {
|
||||
Bool enable;
|
||||
} lock;
|
||||
} system;
|
||||
|
||||
struct Transcript {
|
||||
Bool enable;
|
||||
String replay;
|
||||
} transcript;
|
||||
};
|
||||
|
||||
extern ServerConfig config;
|
||||
|
||||
std::vector<std::string>
|
||||
ParsePreloadCollection(const std::string&);
|
||||
|
||||
std::vector<int64_t>
|
||||
ParseGPUDevices(const std::string&);
|
||||
} // namespace milvus
|
||||
@ -1,19 +0,0 @@
|
||||
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "value/config/ServerConfig.h"
|
||||
|
||||
TEST(ServerConfigTest, parse_invalid_devices) {
|
||||
auto collections = milvus::ParseGPUDevices("gpu0,gpu1");
|
||||
ASSERT_EQ(collections.size(), 0);
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
// 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 "value/status/ServerStatus.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
ServerStatus server_status;
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,31 +0,0 @@
|
||||
// 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 <string>
|
||||
|
||||
#include "value/Value.h"
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
struct ServerStatus {
|
||||
using String = Value<std::string>;
|
||||
using Bool = Value<bool>;
|
||||
using Integer = Value<int64_t>;
|
||||
using Floating = Value<double>;
|
||||
|
||||
Bool indexing;
|
||||
};
|
||||
|
||||
extern ServerStatus server_status;
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,48 +0,0 @@
|
||||
// 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 <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "value/status/ServerStatus.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
#define Bool_(name, modifiable, default, is_valid) \
|
||||
{ #name, CreateBoolValue(#name, modifiable, server_status.name, default, is_valid) }
|
||||
#define String_(name, modifiable, default, is_valid) \
|
||||
{ #name, CreateStringValue(#name, modifiable, server_status.name, default, is_valid) }
|
||||
#define Enum_(name, modifiable, enumd, default, is_valid) \
|
||||
{ #name, CreateEnumValue(#name, modifiable, enumd, server_status.name, default, is_valid) }
|
||||
#define Integer_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateIntegerValue(#name, modifiable, lower_bound, upper_bound, server_status.name, default, is_valid) }
|
||||
#define Floating_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateFloatingValue(#name, modifiable, lower_bound, upper_bound, server_status.name, default, is_valid) }
|
||||
#define Size_(name, modifiable, lower_bound, upper_bound, default, is_valid) \
|
||||
{ #name, CreateSizeValue(#name, modifiable, lower_bound, upper_bound, server_status.name, default, is_valid) }
|
||||
|
||||
#define Bool(name, default) Bool_(name, true, default, nullptr)
|
||||
#define String(name, default) String_(name, true, default, nullptr)
|
||||
#define Enum(name, enumd, default) Enum_(name, true, enumd, default, nullptr)
|
||||
#define Integer(name, lower_bound, upper_bound, default) \
|
||||
Integer_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
#define Floating(name, lower_bound, upper_bound, default) \
|
||||
Floating_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
#define Size(name, lower_bound, upper_bound, default) Size_(name, true, lower_bound, upper_bound, default, nullptr)
|
||||
|
||||
std::unordered_map<std::string, BaseValuePtr>
|
||||
InitStatus() {
|
||||
return std::unordered_map<std::string, BaseValuePtr>{
|
||||
Bool(indexing, false),
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,55 +0,0 @@
|
||||
// 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 "value/status/StatusMgr.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
extern std::unordered_map<std::string, BaseValuePtr>
|
||||
InitStatus();
|
||||
|
||||
StatusMgr StatusMgr::instance;
|
||||
|
||||
StatusMgr::StatusMgr() : ValueMgr(InitStatus()) {
|
||||
}
|
||||
|
||||
void
|
||||
StatusMgr::Set(const std::string& name, const std::string& value, bool update) {
|
||||
/* Check if existed */
|
||||
if (status_list_.find(name) == status_list_.end()) {
|
||||
throw std::runtime_error("Status " + name + " not found.");
|
||||
}
|
||||
|
||||
try {
|
||||
/* Set value, throws ValueError only. */
|
||||
status_list_.at(name)->Set(value, update);
|
||||
} catch (ValueError& e) {
|
||||
/* Convert to std::runtime_error. */
|
||||
throw std::runtime_error(e.message());
|
||||
} catch (...) {
|
||||
/* Unexpected exception, output status and value. */
|
||||
throw std::runtime_error("Unexpected exception happened when setting " + value + " to " + name + ".");
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
StatusMgr::Get(const std::string& name) const {
|
||||
try {
|
||||
auto& status = status_list_.at(name);
|
||||
return status->Get();
|
||||
} catch (std::out_of_range& ex) {
|
||||
throw std::runtime_error("Status " + name + " not found.");
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Unexpected exception happened when getting status " + name + ".");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
@ -1,47 +0,0 @@
|
||||
// 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 <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "value/ValueMgr.h"
|
||||
#include "value/ValueType.h"
|
||||
|
||||
namespace milvus {
|
||||
|
||||
class StatusMgr : public ValueMgr {
|
||||
public:
|
||||
static ValueMgr&
|
||||
GetInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static StatusMgr instance;
|
||||
|
||||
public:
|
||||
StatusMgr();
|
||||
|
||||
/* throws std::exception only */
|
||||
void
|
||||
Set(const std::string& name, const std::string& value, bool update) override;
|
||||
|
||||
/* throws std::exception only */
|
||||
std::string
|
||||
Get(const std::string& name) const override;
|
||||
|
||||
private:
|
||||
const std::unordered_map<std::string, BaseValuePtr>& status_list_ = value_list_;
|
||||
};
|
||||
|
||||
} // namespace milvus
|
||||
Loading…
x
Reference in New Issue
Block a user