1 /*
2 * Copyright (c) 2021 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 "storage_engine.h"
17
18 #include <algorithm>
19 #include <sys/stat.h>
20
21 #include "db_common.h"
22 #include "db_errno.h"
23 #include "log_print.h"
24
25 namespace DistributedDB {
26 const int StorageEngine::MAX_WAIT_TIME = 30;
27 const int StorageEngine::MAX_WRITE_SIZE = 1;
28 const int StorageEngine::MAX_READ_SIZE = 16;
29
StorageEngine()30 StorageEngine::StorageEngine()
31 : isUpdated_(false),
32 isMigrating_(false),
33 commitNotifyFunc_(nullptr),
34 schemaChangedFunc_(nullptr),
35 isSchemaChanged_(false),
36 isEnhance_(false),
37 isInitialized_(false),
38 perm_(OperatePerm::NORMAL_PERM),
39 operateAbort_(false),
40 isExistConnection_(false),
41 readPendingCount_(0),
42 externalReadPendingCount_(0),
43 engineState_(EngineState::INVALID)
44 {}
45
~StorageEngine()46 StorageEngine::~StorageEngine()
47 {
48 LOGI("[StorageEngine] close executor");
49 CloseExecutor();
50 }
51
CloseAllExecutor()52 void StorageEngine::CloseAllExecutor()
53 {
54 CloseExecutor();
55 }
56
InitAllReadWriteExecutor()57 int StorageEngine::InitAllReadWriteExecutor()
58 {
59 return InitReadWriteExecutors();
60 }
61
GetOption() const62 OpenDbProperties StorageEngine::GetOption() const
63 {
64 std::lock_guard<std::mutex> autoLock(optionMutex_);
65 return option_;
66 }
67
InitReadWriteExecutors()68 int StorageEngine::InitReadWriteExecutors()
69 {
70 PrintDbFileMsg(true);
71 int errCode = E_OK;
72 std::scoped_lock initLock(writeMutex_, readMutex_);
73 // only for create the database avoid the minimum number is 0.
74 StorageExecutor *handle = nullptr;
75 if (engineAttr_.minReadNum == 0 && engineAttr_.minWriteNum == 0) {
76 errCode = CreateNewExecutor(true, handle);
77 if (errCode != E_OK) {
78 return errCode;
79 }
80
81 if (handle != nullptr) {
82 delete handle;
83 handle = nullptr;
84 }
85 }
86
87 for (uint32_t i = 0; i < engineAttr_.minWriteNum; i++) {
88 handle = nullptr;
89 errCode = CreateNewExecutor(true, handle);
90 if (errCode != E_OK) {
91 return errCode;
92 }
93 AddStorageExecutor(handle, false);
94 }
95
96 for (uint32_t i = 0; i < engineAttr_.minReadNum; i++) {
97 handle = nullptr;
98 errCode = CreateNewExecutor(false, handle);
99 if (errCode != E_OK) {
100 return errCode;
101 }
102 AddStorageExecutor(handle, false);
103 }
104 return E_OK;
105 }
106
107
Init(bool isEnhance)108 int StorageEngine::Init(bool isEnhance)
109 {
110 if (isInitialized_.load()) {
111 LOGD("Storage engine has been initialized!");
112 return E_OK;
113 }
114 isEnhance_ = isEnhance;
115
116 int errCode = InitReadWriteExecutors();
117 if (errCode == E_OK) {
118 isInitialized_.store(true);
119 initCondition_.notify_all();
120 return E_OK;
121 } else if (errCode == -E_EKEYREVOKED) {
122 // Assumed file system has classification function, can only get one write handle
123 std::unique_lock<std::mutex> lock(writeMutex_);
124 if (!writeIdleList_.empty() || !writeUsingList_.empty()) {
125 isInitialized_.store(true);
126 initCondition_.notify_all();
127 return E_OK;
128 }
129 }
130 initCondition_.notify_all();
131 Release();
132 return errCode;
133 }
134
ReInit()135 int StorageEngine::ReInit()
136 {
137 return E_OK;
138 }
139
FindExecutor(bool writable,OperatePerm perm,int & errCode,bool isExternal,int waitTime)140 StorageExecutor *StorageEngine::FindExecutor(bool writable, OperatePerm perm, int &errCode, bool isExternal,
141 int waitTime)
142 {
143 if (GetEngineState() == EngineState::ENGINE_BUSY) {
144 LOGI("Storage engine is busy!");
145 errCode = -E_BUSY;
146 return nullptr;
147 }
148
149 {
150 std::unique_lock<std::mutex> lock(initMutex_);
151 bool result = initCondition_.wait_for(lock, std::chrono::seconds(waitTime), [this]() {
152 return isInitialized_.load();
153 });
154 if (!result || !isInitialized_.load()) {
155 LOGE("Storage engine is not initialized");
156 errCode = -E_BUSY; // Usually in reinitialize engine, return BUSY
157 return nullptr;
158 }
159 }
160
161 if (writable) {
162 return FindWriteExecutor(perm, errCode, waitTime, isExternal);
163 }
164
165 return FindReadExecutor(perm, errCode, waitTime, isExternal);
166 }
167
FindWriteExecutor(OperatePerm perm,int & errCode,int waitTime,bool isExternal)168 StorageExecutor *StorageEngine::FindWriteExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal)
169 {
170 LOGD("[FindWriteExecutor]Finding WriteExecutor");
171 std::unique_lock<std::mutex> lock(writeMutex_);
172 errCode = -E_BUSY;
173 if (perm_ == OperatePerm::DISABLE_PERM || perm_ != perm) {
174 LOGI("Not permitted to get the executor[%u]", static_cast<unsigned>(perm_));
175 return nullptr;
176 }
177 std::list<StorageExecutor *> &writeUsingList = isExternal ? externalWriteUsingList_ : writeUsingList_;
178 std::list<StorageExecutor *> &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_;
179 if (waitTime <= 0) { // non-blocking.
180 if (writeUsingList.empty() &&
181 writeIdleList.size() + writeUsingList.size() == engineAttr_.maxWriteNum) {
182 return nullptr;
183 }
184 return FetchStorageExecutor(true, writeIdleList, writeUsingList, errCode, isExternal);
185 }
186 // Not prohibited and there is an available handle
187 bool result = writeCondition_.wait_for(lock, std::chrono::seconds(waitTime),
188 [this, &perm, &writeUsingList, &writeIdleList]() {
189 return (perm_ == OperatePerm::NORMAL_PERM || perm_ == perm) && (!writeIdleList.empty() ||
190 (writeIdleList.size() + writeUsingList.size() < engineAttr_.maxWriteNum) ||
191 operateAbort_);
192 });
193 if (operateAbort_) {
194 LOGI("Abort write executor and executor and busy for operate!");
195 return nullptr;
196 }
197 if (!result) {
198 LOGI("Get write handle result[%d], permissType[%u], operType[%u], write[%zu-%zu-%" PRIu32 "]", result,
199 static_cast<unsigned>(perm_), static_cast<unsigned>(perm), writeIdleList.size(), writeUsingList.size(),
200 engineAttr_.maxWriteNum);
201 return nullptr;
202 }
203 return FetchStorageExecutor(true, writeIdleList, writeUsingList, errCode, isExternal);
204 }
205
FindReadExecutor(OperatePerm perm,int & errCode,int waitTime,bool isExternal)206 StorageExecutor *StorageEngine::FindReadExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal)
207 {
208 auto &pendingCount = isExternal ? externalReadPendingCount_ : readPendingCount_;
209 bool isNeedCreate = false;
210 {
211 std::unique_lock<std::mutex> lock(readMutex_);
212 errCode = -E_BUSY;
213 if (perm_ == OperatePerm::DISABLE_PERM || perm_ != perm) {
214 LOGI("Not permitted to get the executor[%u]", static_cast<unsigned>(perm_));
215 return nullptr;
216 }
217 std::list<StorageExecutor *> &readUsingList = isExternal ? externalReadUsingList_ : readUsingList_;
218 std::list<StorageExecutor *> &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_;
219 if (waitTime <= 0) { // non-blocking.
220 auto pending = static_cast<size_t>(pendingCount.load());
221 if (readIdleList.empty() && readUsingList.size() + pending == engineAttr_.maxReadNum) {
222 return nullptr;
223 }
224 } else {
225 // Not prohibited and there is an available handle
226 uint32_t maxReadHandleNum = isExternal ? 1 : engineAttr_.maxReadNum;
227 bool result = readCondition_.wait_for(lock, std::chrono::seconds(waitTime),
228 [this, &perm, &readUsingList, &readIdleList, &maxReadHandleNum, &pendingCount]() {
229 auto pending = static_cast<size_t>(pendingCount.load());
230 bool isHandleLessMax;
231 if (readIdleList.size() > pending) {
232 // readIdleList.size() + readUsingList.size() - 1 should not greater than maxReadHandleNum
233 // -1 because handle will use from idle list
234 isHandleLessMax = readIdleList.size() + readUsingList.size() < maxReadHandleNum + 1;
235 } else {
236 isHandleLessMax = pending + readUsingList.size() < maxReadHandleNum;
237 }
238 return (perm_ == OperatePerm::NORMAL_PERM || perm_ == perm) && (isHandleLessMax || operateAbort_);
239 });
240 if (operateAbort_) {
241 LOGI("Abort find read executor and busy for operate!");
242 return nullptr;
243 }
244 if (!result) {
245 LOGI("Get read handle result[%d], permissType[%u], operType[%u], read[%zu-%zu-%" PRIu32 "]"
246 "pending count[%d]", result, static_cast<unsigned>(perm_), static_cast<unsigned>(perm),
247 readIdleList.size(), readUsingList.size(), engineAttr_.maxReadNum, pendingCount.load());
248 return nullptr;
249 }
250 }
251 pendingCount++;
252 isNeedCreate = readIdleList.size() < static_cast<size_t>(pendingCount.load());
253 }
254 auto executor = FetchReadStorageExecutor(errCode, isExternal, isNeedCreate);
255 readCondition_.notify_all();
256 return executor;
257 }
258
FetchReadStorageExecutor(int & errCode,bool isExternal,bool isNeedCreate)259 StorageExecutor *StorageEngine::FetchReadStorageExecutor(int &errCode, bool isExternal, bool isNeedCreate)
260 {
261 StorageExecutor *handle = nullptr;
262 if (isNeedCreate) {
263 errCode = CreateNewExecutor(false, handle);
264 }
265 std::unique_lock<std::mutex> lock(readMutex_);
266 auto &pendingCount = isExternal ? externalReadPendingCount_ : readPendingCount_;
267 pendingCount--;
268 if (isNeedCreate) {
269 auto &usingList = isExternal ? externalReadUsingList_ : readUsingList_;
270 if ((errCode != E_OK) || (handle == nullptr)) {
271 if (errCode != -E_EKEYREVOKED) {
272 return nullptr;
273 }
274 LOGE("Key revoked status, couldn't create the new executor");
275 if (!usingList.empty()) {
276 LOGE("Can't create new executor for revoked");
277 errCode = -E_BUSY;
278 }
279 return nullptr;
280 }
281 AddStorageExecutor(handle, isExternal);
282 }
283 auto &usingList = isExternal ? externalReadUsingList_ : readUsingList_;
284 auto &idleList = isExternal ? externalReadIdleList_ : readIdleList_;
285 auto item = idleList.front();
286 usingList.push_back(item);
287 idleList.remove(item);
288 if (!isEnhance_) {
289 LOGD("Get executor[0] from [%.3s]", hashIdentifier_.c_str());
290 }
291 errCode = E_OK;
292 return item;
293 }
294
Recycle(StorageExecutor * & handle,bool isExternal)295 void StorageEngine::Recycle(StorageExecutor *&handle, bool isExternal)
296 {
297 if (handle == nullptr) {
298 return;
299 }
300 if (!isEnhance_) {
301 LOGD("Recycle executor[%d] for id[%.6s]", handle->GetWritable(), hashIdentifier_.c_str());
302 }
303 if (handle->GetWritable()) {
304 std::unique_lock<std::mutex> lock(writeMutex_);
305 std::list<StorageExecutor *> &writeUsingList = isExternal ? externalWriteUsingList_ : writeUsingList_;
306 std::list<StorageExecutor *> &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_;
307 auto iter = std::find(writeUsingList.begin(), writeUsingList.end(), handle);
308 if (iter != writeUsingList.end()) {
309 writeUsingList.remove(handle);
310 if (!writeIdleList.empty()) {
311 delete handle;
312 handle = nullptr;
313 return;
314 }
315 handle->Reset();
316 writeIdleList.push_back(handle);
317 writeCondition_.notify_one();
318 idleCondition_.notify_all();
319 }
320 } else {
321 StorageExecutor *releaseHandle = nullptr;
322 {
323 std::unique_lock<std::mutex> lock(readMutex_);
324 std::list<StorageExecutor *> &readUsingList = isExternal ? externalReadUsingList_ : readUsingList_;
325 std::list<StorageExecutor *> &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_;
326 auto iter = std::find(readUsingList.begin(), readUsingList.end(), handle);
327 if (iter != readUsingList.end()) {
328 readUsingList.remove(handle);
329 if (!readIdleList.empty()) {
330 releaseHandle = handle;
331 handle = nullptr;
332 } else {
333 handle->Reset();
334 readIdleList.push_back(handle);
335 readCondition_.notify_one();
336 }
337 }
338 }
339 delete releaseHandle;
340 }
341 handle = nullptr;
342 }
343
ClearCorruptedFlag()344 void StorageEngine::ClearCorruptedFlag()
345 {
346 return;
347 }
348
IsEngineCorrupted() const349 bool StorageEngine::IsEngineCorrupted() const
350 {
351 return false;
352 }
353
Release()354 void StorageEngine::Release()
355 {
356 CloseExecutor();
357 isInitialized_.store(false);
358 isUpdated_ = false;
359 ClearCorruptedFlag();
360 SetEngineState(EngineState::INVALID);
361 }
362
TryToDisable(bool isNeedCheckAll,OperatePerm disableType)363 int StorageEngine::TryToDisable(bool isNeedCheckAll, OperatePerm disableType)
364 {
365 if (engineState_ != EngineState::MAINDB && engineState_ != EngineState::INVALID) {
366 LOGE("Not support disable handle when cacheDB existed! state = [%d]", engineState_);
367 return(engineState_ == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
368 }
369
370 std::lock(writeMutex_, readMutex_);
371 std::lock_guard<std::mutex> writeLock(writeMutex_, std::adopt_lock);
372 std::lock_guard<std::mutex> readLock(readMutex_, std::adopt_lock);
373
374 if (!isNeedCheckAll) {
375 goto END;
376 }
377
378 if (!writeUsingList_.empty() || !readUsingList_.empty() || !externalWriteUsingList_.empty() ||
379 !externalReadUsingList_.empty()) {
380 LOGE("Database handle used");
381 return -E_BUSY;
382 }
383 END:
384 if (perm_ == OperatePerm::NORMAL_PERM) {
385 LOGI("database is disable for re-build:%d", static_cast<int>(disableType));
386 perm_ = disableType;
387 writeCondition_.notify_all();
388 readCondition_.notify_all();
389 }
390 return E_OK;
391 }
392
Enable(OperatePerm enableType)393 void StorageEngine::Enable(OperatePerm enableType)
394 {
395 std::lock(writeMutex_, readMutex_);
396 std::lock_guard<std::mutex> writeLock(writeMutex_, std::adopt_lock);
397 std::lock_guard<std::mutex> readLock(readMutex_, std::adopt_lock);
398 if (perm_ == enableType) {
399 LOGI("Re-enable the database");
400 perm_ = OperatePerm::NORMAL_PERM;
401 writeCondition_.notify_all();
402 readCondition_.notify_all();
403 }
404 }
405
Abort(OperatePerm enableType)406 void StorageEngine::Abort(OperatePerm enableType)
407 {
408 std::lock(writeMutex_, readMutex_);
409 std::lock_guard<std::mutex> writeLock(writeMutex_, std::adopt_lock);
410 std::lock_guard<std::mutex> readLock(readMutex_, std::adopt_lock);
411 if (perm_ == enableType) {
412 LOGI("Abort the handle occupy, release all!");
413 perm_ = OperatePerm::NORMAL_PERM;
414 operateAbort_ = true;
415
416 writeCondition_.notify_all();
417 readCondition_.notify_all();
418 }
419 }
420
IsNeedTobeReleased() const421 bool StorageEngine::IsNeedTobeReleased() const
422 {
423 EngineState engineState = GetEngineState();
424 return ((engineState == EngineState::MAINDB) || (engineState == EngineState::INVALID));
425 }
426
GetIdentifier() const427 const std::string &StorageEngine::GetIdentifier() const
428 {
429 return identifier_;
430 }
431
GetEngineState() const432 EngineState StorageEngine::GetEngineState() const
433 {
434 return engineState_;
435 }
436
SetEngineState(EngineState state)437 void StorageEngine::SetEngineState(EngineState state)
438 {
439 if (state != EngineState::MAINDB) {
440 LOGD("Storage engine state to [%d]!", state);
441 }
442 engineState_ = state;
443 }
444
ExecuteMigrate()445 int StorageEngine::ExecuteMigrate()
446 {
447 LOGW("Migration is not supported!");
448 return -E_NOT_SUPPORT;
449 }
450
SetNotifiedCallback(const std::function<void (int,KvDBCommitNotifyFilterAbleData *)> & callback)451 void StorageEngine::SetNotifiedCallback(const std::function<void(int, KvDBCommitNotifyFilterAbleData *)> &callback)
452 {
453 std::unique_lock<std::shared_mutex> lock(notifyMutex_);
454 commitNotifyFunc_ = callback;
455 }
456
SetConnectionFlag(bool isExisted)457 void StorageEngine::SetConnectionFlag(bool isExisted)
458 {
459 return isExistConnection_.store(isExisted);
460 }
461
IsExistConnection() const462 bool StorageEngine::IsExistConnection() const
463 {
464 return isExistConnection_.load();
465 }
466
CheckEngineOption(const KvDBProperties & kvdbOption) const467 int StorageEngine::CheckEngineOption(const KvDBProperties &kvdbOption) const
468 {
469 return E_OK;
470 }
471
AddStorageExecutor(StorageExecutor * handle,bool isExternal)472 void StorageEngine::AddStorageExecutor(StorageExecutor *handle, bool isExternal)
473 {
474 if (handle == nullptr) {
475 return;
476 }
477
478 if (handle->GetWritable()) {
479 std::list<StorageExecutor *> &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_;
480 writeIdleList.push_back(handle);
481 } else {
482 std::list<StorageExecutor *> &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_;
483 readIdleList.push_back(handle);
484 }
485 }
486
ClearHandleList(std::list<StorageExecutor * > & handleList)487 void ClearHandleList(std::list<StorageExecutor *> &handleList)
488 {
489 for (auto &item : handleList) {
490 if (item != nullptr) {
491 delete item;
492 item = nullptr;
493 }
494 }
495 handleList.clear();
496 }
497
CloseExecutor()498 void StorageEngine::CloseExecutor()
499 {
500 {
501 std::lock_guard<std::mutex> lock(writeMutex_);
502 ClearHandleList(writeIdleList_);
503 ClearHandleList(externalWriteIdleList_);
504 }
505
506 {
507 std::lock_guard<std::mutex> lock(readMutex_);
508 ClearHandleList(readIdleList_);
509 ClearHandleList(externalReadIdleList_);
510 }
511 PrintDbFileMsg(false);
512 }
513
FetchStorageExecutor(bool isWrite,std::list<StorageExecutor * > & idleList,std::list<StorageExecutor * > & usingList,int & errCode,bool isExternal)514 StorageExecutor *StorageEngine::FetchStorageExecutor(bool isWrite, std::list<StorageExecutor *> &idleList,
515 std::list<StorageExecutor *> &usingList, int &errCode, bool isExternal)
516 {
517 if (idleList.empty()) {
518 StorageExecutor *handle = nullptr;
519 errCode = CreateNewExecutor(isWrite, handle);
520 if ((errCode != E_OK) || (handle == nullptr)) {
521 if (errCode != -E_EKEYREVOKED) {
522 return nullptr;
523 }
524 LOGE("Key revoked status, couldn't create the new executor");
525 if (!usingList.empty()) {
526 LOGE("Can't create new executor for revoked");
527 errCode = -E_BUSY;
528 }
529 return nullptr;
530 }
531
532 AddStorageExecutor(handle, isExternal);
533 }
534 auto item = idleList.front();
535 usingList.push_back(item);
536 idleList.remove(item);
537 if (!isEnhance_) {
538 LOGD("Get executor[%d] from [%.3s]", isWrite, hashIdentifier_.c_str());
539 }
540 errCode = E_OK;
541 return item;
542 }
543
CheckEngineAttr(const StorageEngineAttr & poolSize)544 bool StorageEngine::CheckEngineAttr(const StorageEngineAttr &poolSize)
545 {
546 return (poolSize.maxReadNum > MAX_READ_SIZE ||
547 poolSize.maxWriteNum > MAX_WRITE_SIZE ||
548 poolSize.minReadNum > poolSize.maxReadNum ||
549 poolSize.minWriteNum > poolSize.maxWriteNum);
550 }
551
IsMigrating() const552 bool StorageEngine::IsMigrating() const
553 {
554 return isMigrating_.load();
555 }
556
WaitWriteHandleIdle()557 void StorageEngine::WaitWriteHandleIdle()
558 {
559 std::unique_lock<std::mutex> autoLock(idleMutex_);
560 LOGD("Wait wHandle release id[%s]. write[%zu-%zu-%" PRIu32 "]", hashIdentifier_.c_str(),
561 writeIdleList_.size(), writeUsingList_.size(), engineAttr_.maxWriteNum);
562 idleCondition_.wait(autoLock, [this]() {
563 return writeUsingList_.empty();
564 });
565 LOGD("Wait wHandle release finish id[%s]. write[%zu-%zu-%" PRIu32 "]",
566 hashIdentifier_.c_str(), writeIdleList_.size(), writeUsingList_.size(), engineAttr_.maxWriteNum);
567 }
568
IncreaseCacheRecordVersion()569 void StorageEngine::IncreaseCacheRecordVersion()
570 {
571 return;
572 }
573
GetCacheRecordVersion() const574 uint64_t StorageEngine::GetCacheRecordVersion() const
575 {
576 return 0;
577 }
578
GetAndIncreaseCacheRecordVersion()579 uint64_t StorageEngine::GetAndIncreaseCacheRecordVersion()
580 {
581 return 0;
582 }
583
SetSchemaChangedCallback(const std::function<int (void)> & callback)584 void StorageEngine::SetSchemaChangedCallback(const std::function<int(void)> &callback)
585 {
586 std::unique_lock<std::shared_mutex> lock(schemaChangedMutex_);
587 schemaChangedFunc_ = callback;
588 }
589
PrintDbFileMsg(bool isOpen)590 void StorageEngine::PrintDbFileMsg(bool isOpen)
591 {
592 OpenDbProperties option = GetOption();
593 std::string dbFilePath = option.uri;
594 if (option.isMemDb || dbFilePath.empty()) {
595 return;
596 }
597 struct stat dbFileStat;
598 if (memset_s(&dbFileStat, sizeof(struct stat), 0, sizeof(struct stat)) != E_OK) {
599 LOGW("init db file stat fail");
600 return;
601 }
602 stat(dbFilePath.c_str(), &dbFileStat);
603 std::string dbWalFilePath = dbFilePath + "-wal";
604 struct stat dbWalFileStat;
605 if (memset_s(&dbWalFileStat, sizeof(struct stat), 0, sizeof(struct stat)) != E_OK) {
606 LOGW("init db wal file stat fail");
607 return;
608 }
609 stat(dbWalFilePath.c_str(), &dbWalFileStat);
610 std::string dbShmFilePath = dbFilePath + "-shm";
611 struct stat dbShmFileStat;
612 if (memset_s(&dbShmFileStat, sizeof(struct stat), 0, sizeof(struct stat)) != E_OK) {
613 LOGW("init db shm file stat fail");
614 return;
615 }
616 stat(dbShmFilePath.c_str(), &dbShmFileStat);
617 std::string dbDwrFilePath = dbFilePath + "-dwr";
618 struct stat dbDwrFileStat;
619 if (memset_s(&dbDwrFileStat, sizeof(struct stat), 0, sizeof(struct stat)) != E_OK) {
620 LOGW("init db dwr file stat fail");
621 return;
622 }
623 stat(dbDwrFilePath.c_str(), &dbDwrFileStat);
624 std::string stage = isOpen ? "before open db," : "after close db,";
625 #ifdef __linux__
626 LOGI("%s db file: [size: %lld, mtime: %lld, inode: %llu], db-wal file: [size: %lld, mtime: %lld, inode: %llu], "
627 "db-shm file: [size: %lld, mtime: %lld, inode: %llu], db-dwr file: [size: %lld, mtime: %lld, inode: %llu]",
628 stage.c_str(), dbFileStat.st_size, dbFileStat.st_mtim.tv_sec, dbFileStat.st_ino, dbWalFileStat.st_size,
629 dbWalFileStat.st_mtim.tv_sec, dbWalFileStat.st_ino, dbShmFileStat.st_size, dbShmFileStat.st_mtim.tv_sec,
630 dbShmFileStat.st_ino, dbDwrFileStat.st_size, dbDwrFileStat.st_mtim.tv_sec, dbDwrFileStat.st_ino);
631 #endif
632 }
633
SetUri(const std::string & uri)634 void StorageEngine::SetUri(const std::string &uri)
635 {
636 std::lock_guard<std::mutex> autoLock(optionMutex_);
637 option_.uri = uri;
638 }
639
SetSQL(const std::vector<std::string> & sql)640 void StorageEngine::SetSQL(const std::vector<std::string> &sql)
641 {
642 std::lock_guard<std::mutex> autoLock(optionMutex_);
643 option_.sqls = sql;
644 }
645
SetSecurityOption(const SecurityOption & option)646 void StorageEngine::SetSecurityOption(const SecurityOption &option)
647 {
648 std::lock_guard<std::mutex> autoLock(optionMutex_);
649 option_.securityOpt = option;
650 }
651
SetCreateIfNecessary(bool isCreateIfNecessary)652 void StorageEngine::SetCreateIfNecessary(bool isCreateIfNecessary)
653 {
654 std::lock_guard<std::mutex> autoLock(optionMutex_);
655 option_.createIfNecessary = isCreateIfNecessary;
656 }
657 }
658