in src/server/pegasus_write_service_impl.h [583:679]
bool validate_check(int64_t decree,
::dsn::apps::cas_check_type::type check_type,
const ::dsn::blob &check_operand,
bool value_exist,
const ::dsn::blob &value,
bool &invalid_argument)
{
invalid_argument = false;
switch (check_type) {
case ::dsn::apps::cas_check_type::CT_NO_CHECK:
return true;
case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EXIST:
return !value_exist;
case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EXIST_OR_EMPTY:
return !value_exist || value.length() == 0;
case ::dsn::apps::cas_check_type::CT_VALUE_EXIST:
return value_exist;
case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EMPTY:
return value_exist && value.length() != 0;
case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_ANYWHERE:
case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_PREFIX:
case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_POSTFIX: {
if (!value_exist)
return false;
if (check_operand.length() == 0)
return true;
if (value.length() < check_operand.length())
return false;
if (check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_ANYWHERE) {
return dsn::string_view(value).find(check_operand) != dsn::string_view::npos;
} else if (check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_PREFIX) {
return dsn::utils::mequals(
value.data(), check_operand.data(), check_operand.length());
} else { // check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_POSTFIX
return dsn::utils::mequals(value.data() + value.length() - check_operand.length(),
check_operand.data(),
check_operand.length());
}
}
case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS:
case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER: {
if (!value_exist)
return false;
int c = dsn::string_view(value).compare(dsn::string_view(check_operand));
if (c < 0) {
return check_type <= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL;
} else if (c == 0) {
return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL &&
check_type <= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL;
} else { // c > 0
return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL;
}
}
case ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS:
case ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_INT_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL:
case ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER: {
if (!value_exist)
return false;
int64_t check_value_int;
if (!dsn::buf2int64(value, check_value_int)) {
// invalid check value
LOG_ERROR_PREFIX("check failed: decree = {}, error = "
"check value \"{}\" is not an integer or out of range",
decree,
utils::c_escape_string(value));
invalid_argument = true;
return false;
}
int64_t check_operand_int;
if (!dsn::buf2int64(check_operand, check_operand_int)) {
// invalid check operand
LOG_ERROR_PREFIX("check failed: decree = {}, error = "
"check operand \"{}\" is not an integer or out of range",
decree,
utils::c_escape_string(check_operand));
invalid_argument = true;
return false;
}
if (check_value_int < check_operand_int) {
return check_type <= ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL;
} else if (check_value_int == check_operand_int) {
return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL &&
check_type <= ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL;
} else { // check_value_int > check_operand_int
return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL;
}
}
default:
CHECK(false, "unsupported check type: {}", check_type);
}
return false;
}