ValidationUtil.cpp 7.2 KB
Newer Older
S
starlord 已提交
1
#include "db/engine/ExecutionEngine.h"
J
jinhai 已提交
2 3 4
#include "ValidationUtil.h"
#include "Log.h"

5
#include <cuda_runtime.h>
J
jinhai 已提交
6

Z
zhiru 已提交
7 8 9 10 11
#include <arpa/inet.h>

#include <regex>
#include <algorithm>

Z
zhiru 已提交
12

J
jinhai 已提交
13 14 15 16
namespace zilliz {
namespace milvus {
namespace server {

17 18 19
constexpr size_t TABLE_NAME_SIZE_LIMIT = 255;
constexpr int64_t TABLE_DIMENSION_LIMIT = 16384;
constexpr int32_t INDEX_FILE_SIZE_LIMIT = 4096; //index trigger size max = 4096 MB
J
jinhai 已提交
20

S
starlord 已提交
21
ErrorCode
22
ValidationUtil::ValidateTableName(const std::string &table_name) {
J
jinhai 已提交
23 24 25 26 27 28 29 30

    // Table name shouldn't be empty.
    if (table_name.empty()) {
        SERVER_LOG_ERROR << "Empty table name";
        return SERVER_INVALID_TABLE_NAME;
    }

    // Table name size shouldn't exceed 16384.
31
    if (table_name.size() > TABLE_NAME_SIZE_LIMIT) {
J
jinhai 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
        SERVER_LOG_ERROR << "Table name size exceed the limitation";
        return SERVER_INVALID_TABLE_NAME;
    }

    // Table name first character should be underscore or character.
    char first_char = table_name[0];
    if (first_char != '_' && std::isalpha(first_char) == 0) {
        SERVER_LOG_ERROR << "Table name first character isn't underscore or character: " << first_char;
        return SERVER_INVALID_TABLE_NAME;
    }

    int64_t table_name_size = table_name.size();
    for (int64_t i = 1; i < table_name_size; ++i) {
        char name_char = table_name[i];
        if (name_char != '_' && std::isalnum(name_char) == 0) {
            SERVER_LOG_ERROR << "Table name character isn't underscore or alphanumber: " << name_char;
            return SERVER_INVALID_TABLE_NAME;
        }
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
55
ErrorCode
56
ValidationUtil::ValidateTableDimension(int64_t dimension) {
57 58
    if (dimension <= 0 || dimension > TABLE_DIMENSION_LIMIT) {
        SERVER_LOG_ERROR << "Table dimension excceed the limitation: " << TABLE_DIMENSION_LIMIT;
J
jinhai 已提交
59
        return SERVER_INVALID_VECTOR_DIMENSION;
Z
zhiru 已提交
60 61
    }
    else {
J
jinhai 已提交
62 63 64 65
        return SERVER_SUCCESS;
    }
}

S
starlord 已提交
66
ErrorCode
67
ValidationUtil::ValidateTableIndexType(int32_t index_type) {
Z
zhiru 已提交
68 69
    int engine_type = (int) engine::EngineType(index_type);
    if (engine_type <= 0 || engine_type > (int) engine::EngineType::MAX_VALUE) {
70
        return SERVER_INVALID_INDEX_TYPE;
J
jinhai 已提交
71
    }
72 73

    return SERVER_SUCCESS;
J
jinhai 已提交
74 75
}

S
starlord 已提交
76
ErrorCode
S
starlord 已提交
77
ValidationUtil::ValidateTableIndexNlist(int32_t nlist) {
Z
zhiru 已提交
78
    if (nlist <= 0) {
S
starlord 已提交
79 80 81 82 83 84
        return SERVER_INVALID_INDEX_NLIST;
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
85
ErrorCode
86
ValidationUtil::ValidateTableIndexFileSize(int64_t index_file_size) {
Z
zhiru 已提交
87
    if (index_file_size <= 0 || index_file_size > INDEX_FILE_SIZE_LIMIT) {
S
starlord 已提交
88 89 90 91 92 93
        return SERVER_INVALID_INDEX_FILE_SIZE;
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
94
ErrorCode
S
starlord 已提交
95
ValidationUtil::ValidateTableIndexMetricType(int32_t metric_type) {
Z
zhiru 已提交
96
    if (metric_type != (int32_t) engine::MetricType::L2 && metric_type != (int32_t) engine::MetricType::IP) {
S
starlord 已提交
97 98 99 100 101
        return SERVER_INVALID_INDEX_METRIC_TYPE;
    }
    return SERVER_SUCCESS;
}

S
starlord 已提交
102
ErrorCode
Z
zhiru 已提交
103
ValidationUtil::ValidateSearchTopk(int64_t top_k, const engine::meta::TableSchema &table_schema) {
104
    if (top_k <= 0 || top_k > 2048) {
105 106 107 108 109 110
        return SERVER_INVALID_TOPK;
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
111
ErrorCode
Z
zhiru 已提交
112
ValidationUtil::ValidateSearchNprobe(int64_t nprobe, const engine::meta::TableSchema &table_schema) {
113 114 115 116 117 118 119
    if (nprobe <= 0 || nprobe > table_schema.nlist_) {
        return SERVER_INVALID_NPROBE;
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
120
ErrorCode
121 122 123 124 125 126 127 128
ValidationUtil::ValidateGpuIndex(uint32_t gpu_index) {
    int num_devices = 0;
    auto cuda_err = cudaGetDeviceCount(&num_devices);
    if (cuda_err) {
        SERVER_LOG_ERROR << "Failed to count video card: " << std::to_string(cuda_err);
        return SERVER_UNEXPECTED_ERROR;
    }

Z
zhiru 已提交
129
    if (gpu_index >= num_devices) {
130 131 132 133 134 135
        return SERVER_INVALID_ARGUMENT;
    }

    return SERVER_SUCCESS;
}

S
starlord 已提交
136
ErrorCode
Z
zhiru 已提交
137
ValidationUtil::GetGpuMemory(uint32_t gpu_index, size_t &memory) {
138 139 140 141 142 143 144 145 146 147 148
    cudaDeviceProp deviceProp;
    auto cuda_err = cudaGetDeviceProperties(&deviceProp, gpu_index);
    if (cuda_err) {
        SERVER_LOG_ERROR << "Failed to get video card properties: " << std::to_string(cuda_err);
        return SERVER_UNEXPECTED_ERROR;
    }

    memory = deviceProp.totalGlobalMem;
    return SERVER_SUCCESS;
}

Z
zhiru 已提交
149
ErrorCode
Z
zhiru 已提交
150
ValidationUtil::ValidateIpAddress(const std::string &ip_address) {
Z
zhiru 已提交
151 152 153 154 155

    struct in_addr address;

    int result = inet_pton(AF_INET, ip_address.c_str(), &address);

Z
zhiru 已提交
156 157 158
    switch (result) {
        case 1:return SERVER_SUCCESS;
        case 0:SERVER_LOG_ERROR << "Invalid IP address: " << ip_address;
Z
zhiru 已提交
159
            return SERVER_INVALID_ARGUMENT;
Z
zhiru 已提交
160
        default:SERVER_LOG_ERROR << "inet_pton conversion error";
Z
zhiru 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
            return SERVER_UNEXPECTED_ERROR;
    }
}

ErrorCode
ValidationUtil::ValidateStringIsNumber(const std::string &string) {
    if (!string.empty() && std::all_of(string.begin(), string.end(), ::isdigit)) {
        return SERVER_SUCCESS;
    }
    else {
        return SERVER_INVALID_ARGUMENT;
    }
}

ErrorCode
ValidationUtil::ValidateStringIsBool(std::string &str) {
    std::transform(str.begin(), str.end(), str.begin(), ::tolower);
    if (str == "true" || str == "on" || str == "yes" || str == "1" ||
        str == "false" || str == "off" || str == "no" || str == "0" ||
        str.empty()) {
        return SERVER_SUCCESS;
    }
    else {
        return SERVER_INVALID_ARGUMENT;
    }
}

ErrorCode
ValidationUtil::ValidateStringIsDouble(const std::string &str, double &val) {
Z
zhiru 已提交
190
    char *end = nullptr;
Z
zhiru 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
    val = std::strtod(str.c_str(), &end);
    if (end != str.c_str() && *end == '\0' && val != HUGE_VAL) {
        return SERVER_SUCCESS;
    }
    else {
        return SERVER_INVALID_ARGUMENT;
    }
}

ErrorCode
ValidationUtil::ValidateDbURI(const std::string &uri) {
    std::string dialectRegex = "(.*)";
    std::string usernameRegex = "(.*)";
    std::string passwordRegex = "(.*)";
    std::string hostRegex = "(.*)";
    std::string portRegex = "(.*)";
    std::string dbNameRegex = "(.*)";
    std::string uriRegexStr = dialectRegex + "\\:\\/\\/" +
        usernameRegex + "\\:" +
        passwordRegex + "\\@" +
        hostRegex + "\\:" +
        portRegex + "\\/" +
        dbNameRegex;
    std::regex uriRegex(uriRegexStr);
    std::smatch pieces_match;

    bool okay = true;

    if (std::regex_match(uri, pieces_match, uriRegex)) {
        std::string dialect = pieces_match[1].str();
        std::transform(dialect.begin(), dialect.end(), dialect.begin(), ::tolower);
        if (dialect.find("mysql") == std::string::npos && dialect.find("sqlite") == std::string::npos) {
            SERVER_LOG_ERROR << "Invalid dialect in URI: dialect = " << dialect;
            okay = false;
        }

        std::string host = pieces_match[4].str();
        if (!host.empty() && host != "localhost") {
            if (ValidateIpAddress(host) != SERVER_SUCCESS) {
                SERVER_LOG_ERROR << "Invalid host ip address in uri = " << host;
                okay = false;
            }
        }

        std::string port = pieces_match[5].str();
        if (!port.empty()) {
            if (ValidateStringIsNumber(port) != SERVER_SUCCESS) {
                SERVER_LOG_ERROR << "Invalid port in uri = " << port;
                okay = false;
            }
        }
Z
zhiru 已提交
242 243
    }
    else {
Z
zhiru 已提交
244 245 246 247 248 249 250
        SERVER_LOG_ERROR << "Wrong URI format: URI = " << uri;
        okay = false;
    }

    return (okay ? SERVER_SUCCESS : SERVER_INVALID_ARGUMENT);
}

J
jinhai 已提交
251 252 253
}
}
}