mirror of https://github.com/milvus-io/milvus.git
parent
8c9d5b2bf3
commit
a10c794daf
|
@ -15,6 +15,8 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
@ -26,6 +28,13 @@ std::unordered_map<std::string, int64_t> BYTE_UNITS = {
|
|||
{"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] == '-')) {
|
||||
|
@ -111,7 +120,7 @@ parse_bytes(const std::string& str, std::string& err) {
|
|||
} 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";
|
||||
<< " The postfix should be one of the `b` `k` `m` `g` characters.";
|
||||
err = ss.str();
|
||||
}
|
||||
} catch (...) {
|
||||
|
@ -120,6 +129,31 @@ parse_bytes(const std::string& str, std::string& err) {
|
|||
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.
|
||||
|
@ -487,4 +521,75 @@ SizeValue::Get() {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -270,6 +270,30 @@ class SizeValue : public BaseValue {
|
|||
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) \
|
||||
|
@ -292,4 +316,7 @@ class SizeValue : public BaseValue {
|
|||
#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
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#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 {
|
||||
|
||||
|
@ -101,6 +103,8 @@ is_cachesize_valid(int64_t size, std::string& err) {
|
|||
{ #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)
|
||||
|
@ -110,6 +114,7 @@ is_cachesize_valid(int64_t size, std::string& err) {
|
|||
#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() {
|
||||
|
@ -170,6 +175,7 @@ InitConfig() {
|
|||
Bool(logs.log_to_file, true),
|
||||
|
||||
String(log.min_messages, "warning"),
|
||||
// Time(log.rotation_age, 0, 16384ll * HOURS, 24ll * HOURS),
|
||||
|
||||
/* tracing */
|
||||
String(tracing.json_config_path, ""),
|
||||
|
|
|
@ -146,6 +146,7 @@ struct ServerConfig {
|
|||
|
||||
struct Log {
|
||||
String min_messages;
|
||||
// Integer rotation_age;
|
||||
} log;
|
||||
|
||||
struct System {
|
||||
|
|
Loading…
Reference in New Issue