• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 
16 #include "db_config.h"
17 
18 #include <algorithm>
19 #include <cstring>
20 #include <functional>
21 #include <memory>
22 
23 #include "doc_errno.h"
24 #include "doc_limit.h"
25 #include "json_object.h"
26 #include "log_print.h"
27 
28 namespace DocumentDB {
29 namespace {
30 constexpr int MIN_REDO_BUFFER_SIZE = 256;
31 constexpr int MAX_REDO_BUFFER_SIZE = 16384;
32 constexpr int MIN_CONNECTION_NUM = 16;
33 constexpr int MAX_CONNECTION_NUM = 1024;
34 constexpr int MIN_BUFFER_POOL_SIZE = 1024;
35 constexpr int MAX_BUFFER_POOL_SIZE = 4 * 1024 * 1024;
36 
37 constexpr const char *DB_CONFIG_PAGESIZE = "pagesize";
38 constexpr const char *DB_CONFIG_REDO_FLUSH_BY_TRX = "redoflushbytrx";
39 constexpr const char *DB_CONFIG_REDO_PUB_BUFF_SIZE = "redopubbufsize";
40 constexpr const char *DB_CONFIG_MAX_CONN_NUM = "maxconnnum";
41 constexpr const char *DB_CONFIG_BUFFER_POOL_SIZE = "bufferpoolsize";
42 constexpr const char *DB_CONFIG_CRC_CHECK_ENABLE = "crccheckenable";
43 
44 const int DB_CONFIG_SIZE = 6; // db config size
45 const char *DB_CONFIG[DB_CONFIG_SIZE] = { DB_CONFIG_PAGESIZE, DB_CONFIG_REDO_FLUSH_BY_TRX,
46     DB_CONFIG_REDO_PUB_BUFF_SIZE, DB_CONFIG_MAX_CONN_NUM, DB_CONFIG_BUFFER_POOL_SIZE, DB_CONFIG_CRC_CHECK_ENABLE };
47 
48 template<typename T>
CheckAndGetDBConfig(const JsonObject & config,const std::string & name,const std::function<bool (T)> & checkValid,T & val)49 bool CheckAndGetDBConfig(const JsonObject &config, const std::string &name, const std::function<bool(T)> &checkValid,
50     T &val)
51 {
52     const JsonFieldPath configField = { name };
53     if (!config.IsFieldExists(configField)) {
54         return true;
55     }
56 
57     int errCode = E_OK;
58     ValueObject configValue = config.GetObjectByPath(configField, errCode);
59     if (errCode != E_OK) {
60         GLOGE("Can not find config Value");
61         return errCode;
62     }
63     if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) {
64         GLOGE("Check DB config failed, not found or type of %s is not NUMBER.", name.c_str());
65         return false;
66     }
67 
68     if (checkValid && !checkValid(static_cast<T>(configValue.GetIntValue()))) {
69         GLOGE("Check DB config failed, invalid %s value.", name.c_str());
70         return false;
71     }
72 
73     val = static_cast<T>(configValue.GetIntValue());
74     return true;
75 }
76 
CheckPageSizeConfig(const JsonObject & config,int32_t & pageSize)77 bool CheckPageSizeConfig(const JsonObject &config, int32_t &pageSize)
78 {
79     std::function<bool(int32_t)> checkFunction = [](int32_t val) {
80         static const std::vector<int32_t> pageSizeValid = { 4, 8, 16, 32, 64 };
81         return std::find(pageSizeValid.begin(), pageSizeValid.end(), val) != pageSizeValid.end();
82     };
83     return CheckAndGetDBConfig(config, DB_CONFIG_PAGESIZE, checkFunction, pageSize);
84 }
85 
CheckRedoFlushConfig(const JsonObject & config,uint32_t & redoFlush)86 bool CheckRedoFlushConfig(const JsonObject &config, uint32_t &redoFlush)
87 {
88     std::function<bool(uint32_t)> checkFunction = [](uint32_t val) {
89         return val == 0 || val == 1;
90     };
91     return CheckAndGetDBConfig(config, DB_CONFIG_REDO_FLUSH_BY_TRX, checkFunction, redoFlush);
92 }
93 
CheckRedoBufSizeConfig(const JsonObject & config,int32_t pageSize,uint32_t & redoBufSize)94 bool CheckRedoBufSizeConfig(const JsonObject &config, int32_t pageSize, uint32_t &redoBufSize)
95 {
96     std::function<bool(uint32_t)> checkFunction = [pageSize](uint32_t val) {
97         return val >= MIN_REDO_BUFFER_SIZE && val <= MAX_REDO_BUFFER_SIZE &&
98             val > static_cast<uint32_t>(pageSize * 63); // 63: pool size should be 63 times larger then pageSize
99     };
100     return CheckAndGetDBConfig(config, DB_CONFIG_REDO_PUB_BUFF_SIZE, checkFunction, redoBufSize);
101 }
102 
CheckMaxConnNumConfig(const JsonObject & config,int32_t & maxConnNum)103 bool CheckMaxConnNumConfig(const JsonObject &config, int32_t &maxConnNum)
104 {
105     std::function<bool(int32_t)> checkFunction = [](int32_t val) {
106         return val >= MIN_CONNECTION_NUM && val <= MAX_CONNECTION_NUM;
107     };
108     return CheckAndGetDBConfig(config, DB_CONFIG_MAX_CONN_NUM, checkFunction, maxConnNum);
109 }
110 
CheckBufferPoolSizeConfig(const JsonObject & config,int32_t pageSize,uint32_t & redoBufSize)111 bool CheckBufferPoolSizeConfig(const JsonObject &config, int32_t pageSize, uint32_t &redoBufSize)
112 {
113     std::function<bool(uint32_t)> checkFunction = [pageSize](uint32_t val) {
114         return val >= MIN_BUFFER_POOL_SIZE && val <= MAX_BUFFER_POOL_SIZE &&
115             val >= static_cast<uint32_t>(pageSize * 64); // 64: pool size should be 64 times larger then pageSize
116     };
117     return CheckAndGetDBConfig(config, DB_CONFIG_BUFFER_POOL_SIZE, checkFunction, redoBufSize);
118 }
119 
CheckCrcCheckEnableConfig(const JsonObject & config,uint32_t & crcCheckEnable)120 bool CheckCrcCheckEnableConfig(const JsonObject &config, uint32_t &crcCheckEnable)
121 {
122     std::function<bool(uint32_t)> checkFunction = [](uint32_t val) {
123         return val == 0 || val == 1;
124     };
125     return CheckAndGetDBConfig(config, DB_CONFIG_CRC_CHECK_ENABLE, checkFunction, crcCheckEnable);
126 }
127 
CheckConfigValid(const JsonObject & config)128 int CheckConfigValid(const JsonObject &config)
129 {
130     JsonObject child = config.GetChild();
131     while (!child.IsNull()) {
132         std::string fieldName = child.GetItemField();
133         bool isSupport = false;
134         for (int i = 0; i < DB_CONFIG_SIZE; i++) {
135             if (strcmp(DB_CONFIG[i], fieldName.c_str()) == 0) {
136                 isSupport = true;
137                 break;
138             }
139         }
140 
141         if (!isSupport) {
142             GLOGE("Invalid db config.");
143             return -E_INVALID_CONFIG_VALUE;
144         }
145 
146         child = child.GetNext();
147     }
148     return E_OK;
149 }
150 } // namespace
151 
GetDBConfigFromJsonStr(const std::string & confStr,int & errCode)152 DBConfig DBConfig::GetDBConfigFromJsonStr(const std::string &confStr, int &errCode)
153 {
154     JsonObject dbConfig = JsonObject::Parse(confStr, errCode);
155     if (errCode != E_OK) {
156         GLOGE("Read DB config failed from str. %d", errCode);
157         return {};
158     }
159 
160     errCode = CheckConfigValid(dbConfig);
161     if (errCode != E_OK) {
162         GLOGE("Check DB config, not support config item. %d", errCode);
163         return {};
164     }
165 
166     DBConfig conf;
167     if (!CheckPageSizeConfig(dbConfig, conf.pageSize_)) {
168         GLOGE("Check DB config 'pageSize' failed.");
169         errCode = -E_INVALID_CONFIG_VALUE;
170         return {};
171     }
172 
173     if (!CheckRedoFlushConfig(dbConfig, conf.redoFlushByTrx_)) {
174         GLOGE("Check DB config 'redoFlushByTrx' failed.");
175         errCode = -E_INVALID_CONFIG_VALUE;
176         return {};
177     }
178 
179     if (!CheckRedoBufSizeConfig(dbConfig, conf.pageSize_, conf.redoPubBufSize_)) {
180         GLOGE("Check DB config 'redoPubBufSize' failed.");
181         errCode = -E_INVALID_CONFIG_VALUE;
182         return {};
183     }
184 
185     if (!CheckMaxConnNumConfig(dbConfig, conf.maxConnNum_)) {
186         GLOGE("Check DB config 'maxConnNum' failed.");
187         errCode = -E_INVALID_CONFIG_VALUE;
188         return {};
189     }
190 
191     if (!CheckBufferPoolSizeConfig(dbConfig, conf.pageSize_, conf.bufferPoolSize_)) {
192         GLOGE("Check DB config 'bufferPoolSize' failed.");
193         errCode = -E_INVALID_CONFIG_VALUE;
194         return {};
195     }
196 
197     if (!CheckCrcCheckEnableConfig(dbConfig, conf.crcCheckEnable_)) {
198         GLOGE("Check DB config 'crcCheckEnable' failed.");
199         errCode = -E_INVALID_CONFIG_VALUE;
200         return {};
201     }
202 
203     conf.configStr_ = confStr;
204     errCode = E_OK;
205     return conf;
206 }
207 
ReadConfig(const std::string & confStr,int & errCode)208 DBConfig DBConfig::ReadConfig(const std::string &confStr, int &errCode)
209 {
210     if (confStr.empty()) {
211         return {};
212     }
213 
214     if (confStr.length() + 1 > MAX_DB_CONFIG_LEN) {
215         GLOGE("Config json string is too long.");
216         errCode = -E_OVER_LIMIT;
217         return {};
218     }
219 
220     std::string lowerCaseConfStr = confStr;
221     std::transform(lowerCaseConfStr.begin(), lowerCaseConfStr.end(), lowerCaseConfStr.begin(), [](unsigned char c) {
222         return std::tolower(c);
223     });
224 
225     return GetDBConfigFromJsonStr(lowerCaseConfStr, errCode);
226 }
227 
ToString() const228 std::string DBConfig::ToString() const
229 {
230     return configStr_;
231 }
232 
GetPageSize() const233 int32_t DBConfig::GetPageSize() const
234 {
235     return pageSize_;
236 }
237 
operator ==(const DBConfig & targetConfig) const238 bool DBConfig::operator==(const DBConfig &targetConfig) const
239 {
240     return pageSize_ == targetConfig.pageSize_ && redoFlushByTrx_ == targetConfig.redoFlushByTrx_ &&
241         redoPubBufSize_ == targetConfig.redoPubBufSize_ && maxConnNum_ == targetConfig.maxConnNum_ &&
242         bufferPoolSize_ == targetConfig.bufferPoolSize_ && crcCheckEnable_ == targetConfig.crcCheckEnable_;
243 }
244 
operator !=(const DBConfig & targetConfig) const245 bool DBConfig::operator!=(const DBConfig &targetConfig) const
246 {
247     return !(*this == targetConfig);
248 }
249 
CheckPersistenceEqual(const DBConfig & targetConfig) const250 bool DBConfig::CheckPersistenceEqual(const DBConfig &targetConfig) const
251 {
252     return pageSize_ == targetConfig.pageSize_ && crcCheckEnable_ == targetConfig.crcCheckEnable_;
253 }
254 } // namespace DocumentDB