• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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