• 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 #ifndef OMIT_MULTI_VER
17 #include "multi_ver_natural_store.h"
18 
19 #include <cstdio>
20 #include <openssl/rand.h>
21 
22 #include "securec.h"
23 
24 #include "db_constant.h"
25 #include "ikvdb_factory.h"
26 #include "db_common.h"
27 #include "endian_convert.h"
28 #include "log_print.h"
29 #include "db_errno.h"
30 #include "multi_ver_storage_engine.h"
31 #include "multi_ver_natural_store_connection.h"
32 #include "generic_multi_ver_kv_entry.h"
33 #include "sqlite_multi_ver_data_storage.h"
34 #include "multi_ver_natural_store_commit_storage.h"
35 #include "multi_ver_vacuum_executor_impl.h"
36 #include "kvdb_utils.h"
37 #include "sqlite_utils.h"
38 #include "platform_specific.h"
39 #include "package_file.h"
40 #include "multi_ver_database_oper.h"
41 
42 namespace DistributedDB {
43 namespace {
44     // file block doesn't support the atomic of the upgrade temporarily.
45     struct VersionFileBlock {
46         static const uint64_t MAGIC_NUMBER = 0x37F8C35AULL;
47         uint64_t magic = MAGIC_NUMBER; // magic number.
48         uint32_t fileVersion = VERSION_FILE_VERSION_CURRENT; // file format version.
49         uint32_t version = 0U; // version of the database.
50         uint8_t tag[MULTI_VER_TAG_SIZE] = {0}; // tag of the multi ver branch.
51         uint8_t reserved[72] = {0}; // reserved data.
52         uint8_t checkSum[32] = {0}; // check sum
53     };
54 
TransferHostFileBlockToNet(VersionFileBlock & block)55     void TransferHostFileBlockToNet(VersionFileBlock &block)
56     {
57         block.magic = HostToNet(block.magic);
58         block.fileVersion = HostToNet(block.fileVersion);
59         block.version = HostToNet(block.version);
60     }
61 
TransferNetFileBlockToHost(VersionFileBlock & block)62     void TransferNetFileBlockToHost(VersionFileBlock &block)
63     {
64         block.magic = NetToHost(block.magic);
65         block.fileVersion = NetToHost(block.fileVersion);
66         block.version = NetToHost(block.version);
67     }
68 
CalcFileBlockCheckSum(VersionFileBlock & block)69     int CalcFileBlockCheckSum(VersionFileBlock &block)
70     {
71         std::vector<uint8_t> vect(reinterpret_cast<uint8_t *>(&block),
72             reinterpret_cast<uint8_t *>(&block) + sizeof(block) - sizeof(block.checkSum));
73         std::vector<uint8_t> hashVect;
74         int errCode = DBCommon::CalcValueHash(vect, hashVect);
75         if (errCode != E_OK) {
76             return errCode;
77         }
78         errCode = memcpy_s(block.checkSum, sizeof(block.checkSum), hashVect.data(), hashVect.size());
79         if (errCode != EOK) {
80             return -E_SECUREC_ERROR;
81         }
82         return E_OK;
83     }
84 
CheckFileBlock(VersionFileBlock & block)85     int CheckFileBlock(VersionFileBlock &block)
86     {
87         uint64_t readMagic = NetToHost(block.magic);
88         if (readMagic != block.MAGIC_NUMBER) {
89             LOGE("Invalid file head");
90             return -E_UNEXPECTED_DATA;
91         }
92 
93         std::vector<uint8_t> vect(reinterpret_cast<uint8_t *>(&block),
94             reinterpret_cast<uint8_t *>(&block) + sizeof(block) - sizeof(block.checkSum));
95         std::vector<uint8_t> hashVect;
96         int errCode = DBCommon::CalcValueHash(vect, hashVect);
97         if (errCode != E_OK) {
98             return errCode;
99         }
100         if (memcmp(hashVect.data(), block.checkSum, sizeof(block.checkSum)) != 0) {
101             LOGE("Check block error");
102             return -E_UNEXPECTED_DATA;
103         }
104 
105         return E_OK;
106     }
107 
CreateNewVersionFile(const std::string & versionFileDir,uint32_t version,std::vector<uint8_t> & tag)108     int CreateNewVersionFile(const std::string &versionFileDir, uint32_t version, std::vector<uint8_t> &tag)
109     {
110         VersionFileBlock block;
111         block.version = version;
112     #ifdef SQLITE_HAS_CODEC
113         RAND_bytes(block.tag, sizeof(block.tag));
114     #endif
115         int errCode = memset_s(block.reserved, sizeof(block.reserved), 0, sizeof(block.reserved));
116         if (errCode != EOK) {
117             return -E_SECUREC_ERROR;
118         }
119 
120         TransferHostFileBlockToNet(block);
121         errCode = CalcFileBlockCheckSum(block);
122         if (errCode != E_OK) {
123             return errCode;
124         }
125         FILE *versionFile = fopen(versionFileDir.c_str(), "wb+");
126         if (versionFile == nullptr) {
127             LOGE("Open the version file error:%d", errno);
128             return -E_SYSTEM_API_FAIL;
129         }
130         size_t writeSize = fwrite(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
131         if (writeSize != sizeof(VersionFileBlock)) {
132             LOGE("Write version file head error:%d", errno);
133             errCode = -E_SYSTEM_API_FAIL;
134         } else {
135             errCode = E_OK;
136             tag.assign(block.tag, block.tag + sizeof(block.tag));
137         }
138 
139         fclose(versionFile);
140         versionFile = nullptr;
141         return errCode;
142     }
143 
ChangeVersionFile(const std::string & versionFileDir,uint32_t version,std::vector<uint8_t> & tag,bool isChangeTag)144     int ChangeVersionFile(const std::string &versionFileDir, uint32_t version, std::vector<uint8_t> &tag,
145         bool isChangeTag)
146     {
147         FILE *versionFile = fopen(versionFileDir.c_str(), "rb+");
148         if (versionFile == nullptr) {
149             LOGE("Open the version file error:%d", errno);
150             return -E_SYSTEM_API_FAIL;
151         }
152         VersionFileBlock block;
153         size_t operateSize = fread(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
154         if (operateSize != sizeof(VersionFileBlock)) {
155             fclose(versionFile);
156             LOGE("Read file error:%d", errno);
157             return -E_SYSTEM_API_FAIL;
158         };
159         int errCode = CheckFileBlock(block);
160         if (errCode != E_OK) {
161             goto END;
162         }
163         TransferHostFileBlockToNet(block);
164         block.version = version;
165 
166         if (isChangeTag) {
167             RAND_bytes(block.tag, sizeof(block.tag));
168             tag.assign(block.tag, block.tag + sizeof(block.tag));
169         }
170 
171         TransferHostFileBlockToNet(block);
172         errCode = CalcFileBlockCheckSum(block);
173         if (errCode != E_OK) {
174             goto END;
175         }
176 #ifdef OS_TYPE_MAC
177         fseeko(versionFile, 0LL, SEEK_SET);
178 #else
179         fseeko64(versionFile, 0LL, SEEK_SET);
180 #endif
181         operateSize = fwrite(&block, 1, sizeof(VersionFileBlock), versionFile);
182         if (operateSize != sizeof(VersionFileBlock)) {
183             LOGE("write the file error:%d", errno);
184             errCode = -E_SYSTEM_API_FAIL;
185             goto END;
186         }
187     END:
188         fclose(versionFile);
189         versionFile = nullptr;
190         return errCode;
191     }
192 
GetVersionAndTag(const std::string & versionFileDir,uint32_t & version,std::vector<uint8_t> & tag)193     int GetVersionAndTag(const std::string &versionFileDir, uint32_t &version, std::vector<uint8_t> &tag)
194     {
195         FILE *versionFile = fopen(versionFileDir.c_str(), "rb+");
196         if (versionFile == nullptr) {
197             LOGE("Open the version file error:%d", errno);
198             return -E_SYSTEM_API_FAIL;
199         }
200         int errCode = E_OK;
201         VersionFileBlock block;
202         size_t readSize = fread(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
203         if (readSize != sizeof(VersionFileBlock)) {
204             LOGE("read the file error:%d", errno);
205             errCode = -E_SYSTEM_API_FAIL;
206             goto END;
207         };
208         errCode = CheckFileBlock(block);
209         if (errCode != E_OK) {
210             LOGE("Check the file block error");
211             goto END;
212         }
213         TransferNetFileBlockToHost(block);
214         version = block.version;
215         tag.assign(block.tag, block.tag + sizeof(block.tag));
216     END:
217         fclose(versionFile);
218         versionFile = nullptr;
219         return errCode;
220     }
221 }
222 
223 MultiVerVacuum MultiVerNaturalStore::shadowTrimmer_;
MultiVerNaturalStore()224 MultiVerNaturalStore::MultiVerNaturalStore()
225     : multiVerData_(nullptr),
226       commitHistory_(nullptr),
227       multiVerKvStorage_(nullptr),
228       multiVerEngine_(nullptr),
229       trimmerImpl_(nullptr),
230       maxRecordTimestamp_(0),
231       maxCommitVersion_(0)
232 {}
233 
~MultiVerNaturalStore()234 MultiVerNaturalStore::~MultiVerNaturalStore()
235 {
236     Clear();
237     UnRegisterNotificationEventType(NATURAL_STORE_COMMIT_EVENT);
238 }
239 
Clear()240 void MultiVerNaturalStore::Clear()
241 {
242     if (trimmerImpl_ != nullptr) {
243         shadowTrimmer_.Abort(GetStringIdentifier());
244         delete trimmerImpl_;
245         trimmerImpl_ = nullptr;
246     }
247     {
248         std::lock_guard<std::mutex> lock(commitHistMutex_);
249         if (commitHistory_ != nullptr) {
250             commitHistory_->Close();
251             delete commitHistory_;
252             commitHistory_ = nullptr;
253         }
254     }
255     {
256         std::lock_guard<std::mutex> lock(multiDataMutex_);
257         if (multiVerData_ != nullptr) {
258             multiVerData_->Close();
259             delete multiVerData_;
260             multiVerData_ = nullptr;
261         }
262     }
263 
264     {
265         std::lock_guard<std::mutex> lock(syncerKvMutex_);
266         if (multiVerKvStorage_ != nullptr) {
267             multiVerKvStorage_->Close();
268             delete multiVerKvStorage_;
269             multiVerKvStorage_ = nullptr;
270         }
271     }
272     multiVerEngine_ = nullptr;
273 }
274 
InitStorages(const KvDBProperties & kvDBProp,bool isChangeTag)275 int MultiVerNaturalStore::InitStorages(const KvDBProperties &kvDBProp, bool isChangeTag)
276 {
277     std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
278     std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
279     bool isNeedCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
280     CipherType cipherType;
281     CipherPassword passwd;
282     kvDBProp.GetPassword(cipherType, passwd);
283 
284     IKvDBMultiVerDataStorage::Property multiVerProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
285     IKvDBCommitStorage::Property commitProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
286     MultiVerKvDataStorage::Property multiVerKvProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
287 
288     int errCode = DBCommon::CreateStoreDirectory(dataDir, identifierDir, DBConstant::MULTI_SUB_DIR, isNeedCreate);
289     if (errCode != E_OK) {
290         return errCode;
291     }
292 
293     errCode = CheckVersion(kvDBProp);
294     if (errCode != E_OK) {
295         LOGE("Upgrade multi ver failed:%d", errCode);
296         return errCode;
297     }
298 
299     errCode = multiVerData_->Open(multiVerProp);
300     if (errCode != E_OK) {
301         LOGE("MultiVer::InitStorages open  multiVerData fail! errCode[%d]", errCode);
302         return errCode;
303     }
304 
305     errCode = commitHistory_->Open(commitProp);
306     if (errCode != E_OK) {
307         LOGE("MultiVer::InitStorages open  commitHistory fail! errCode[%d]", errCode);
308         return errCode;
309     }
310 
311     errCode = multiVerKvStorage_->Open(multiVerKvProp);
312     if (errCode != E_OK) {
313         LOGE("Open multi ver kv storage failed:%d", errCode);
314         return errCode;
315     }
316 
317     errCode = RecoverFromException();
318     if (errCode != E_OK) {
319         LOGE("Recover multi version storage failed:%d", errCode);
320         return errCode;
321     }
322     return InitStorageContext(isChangeTag);
323 }
324 
CheckSubStorageVersion(const KvDBProperties & kvDBProp,bool & isSubStorageAllExist) const325 int MultiVerNaturalStore::CheckSubStorageVersion(const KvDBProperties &kvDBProp, bool &isSubStorageAllExist) const
326 {
327     std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
328     std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
329     bool isNeedCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
330     CipherType cipherType;
331     CipherPassword passwd;
332     kvDBProp.GetPassword(cipherType, passwd);
333 
334     IKvDBMultiVerDataStorage::Property multiVerProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
335     IKvDBCommitStorage::Property commitProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
336     MultiVerKvDataStorage::Property multiVerKvProp = {dataDir, identifierDir, true, cipherType, passwd};
337 
338     bool isDataStorageExist = false;
339     bool isCommitStorageExist = false;
340     bool isKvStorageAllExist = false;
341     int errCode = multiVerData_->CheckVersion(multiVerProp, isDataStorageExist);
342     if (errCode != E_OK) {
343         return errCode;
344     }
345     errCode = commitHistory_->CheckVersion(commitProp, isCommitStorageExist);
346     if (errCode != E_OK) {
347         return errCode;
348     }
349     errCode = multiVerKvStorage_->CheckVersion(multiVerKvProp, isKvStorageAllExist);
350     if (errCode != E_OK) {
351         return errCode;
352     }
353     if ((isDataStorageExist != isCommitStorageExist) || (isCommitStorageExist != isKvStorageAllExist)) {
354         // In case failure happens during open progress, some dbFile will not exist, we should recover from this
355         LOGW("[MultiVerStore][CheckSubVer] Detect File Lost, isDataExist=%d, isCommitExist=%d, isKvAllExist=%d.",
356             isDataStorageExist, isCommitStorageExist, isKvStorageAllExist);
357     }
358     isSubStorageAllExist = isDataStorageExist && isCommitStorageExist && isKvStorageAllExist;
359     return E_OK;
360 }
361 
CreateStorages()362 int MultiVerNaturalStore::CreateStorages()
363 {
364     int errCode = E_OK;
365     IKvDBFactory *factory = IKvDBFactory::GetCurrent();
366     if (factory == nullptr) {
367         return -E_INVALID_DB;
368     }
369     multiVerData_ = factory->CreateMultiVerStorage(errCode);
370     if (multiVerData_ == nullptr) {
371         return errCode;
372     }
373 
374     commitHistory_ = factory->CreateMultiVerCommitStorage(errCode);
375     if (commitHistory_ == nullptr) {
376         return errCode;
377     }
378 
379     multiVerKvStorage_ = new (std::nothrow) MultiVerKvDataStorage;
380     if (multiVerKvStorage_ == nullptr) {
381         return -E_OUT_OF_MEMORY;
382     }
383     return E_OK;
384 }
385 
ClearTempFile(const KvDBProperties & kvDBProp)386 int MultiVerNaturalStore::ClearTempFile(const KvDBProperties &kvDBProp)
387 {
388     std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
389         commitHistory_, multiVerKvStorage_);
390     (void)operation->ClearExportedTempFiles(kvDBProp);
391     int errCode = operation->RekeyRecover(kvDBProp);
392     if (errCode != E_OK) {
393         LOGE("Recover for open db failed in multi version:%d", errCode);
394         return errCode;
395     }
396 
397     errCode = operation->ClearImportTempFile(kvDBProp);
398     if (errCode != E_OK) {
399         LOGE("Recover import temp file for open db failed in multi version:%d", errCode);
400     }
401     return errCode;
402 }
403 
404 // Open the database
Open(const KvDBProperties & kvDBProp)405 int MultiVerNaturalStore::Open(const KvDBProperties &kvDBProp)
406 {
407     StorageEngineAttr poolSize = {0, 1, 0, 16}; // 1 write 16 read at most.
408     int errCode = CreateStorages();
409     if (errCode != E_OK) {
410         goto ERROR;
411     }
412 
413     MyProp() = kvDBProp;
414     errCode = ClearTempFile(kvDBProp);
415     if (errCode != E_OK) {
416         goto ERROR;
417     }
418 
419     errCode = InitStorages(kvDBProp);
420     if (errCode != E_OK) {
421         goto ERROR;
422     }
423 
424     errCode = RegisterNotificationEventType(NATURAL_STORE_COMMIT_EVENT);
425     if (errCode != E_OK) {
426         LOGE("RegisterEventType failed!");
427         goto ERROR;
428     }
429 
430     multiVerEngine_ = std::make_unique<MultiVerStorageEngine>();
431     errCode = multiVerEngine_->InitDatabases(this, multiVerData_, commitHistory_, multiVerKvStorage_, poolSize);
432     if (errCode != E_OK) {
433         goto ERROR;
434     }
435     // Start the trimming;
436     trimmerImpl_ = new (std::nothrow) MultiVerVacuumExecutorImpl(this);
437     if (trimmerImpl_ == nullptr) {
438         errCode = -E_OUT_OF_MEMORY;
439         goto ERROR;
440     }
441 
442     shadowTrimmer_.Launch(GetStringIdentifier(), trimmerImpl_);
443     StartSyncer();
444     return E_OK;
445 ERROR:
446     Clear();
447     return errCode;
448 }
449 
Close()450 void MultiVerNaturalStore::Close()
451 {
452     // Abort the trimming;
453     SyncAbleKvDB::Close();
454     Clear();
455 }
456 
NewConnection(int & errCode)457 GenericKvDBConnection *MultiVerNaturalStore::NewConnection(int &errCode)
458 {
459     auto connection = new (std::nothrow) MultiVerNaturalStoreConnection(this);
460     if (connection == nullptr) {
461         errCode = -E_OUT_OF_MEMORY;
462         return nullptr;
463     }
464 
465     errCode = E_OK;
466     return connection;
467 }
468 
469 // Get interface for syncer.
GetSyncInterface()470 IKvDBSyncInterface *MultiVerNaturalStore::GetSyncInterface()
471 {
472     return this;
473 }
474 
475 // Get interface type of this kvdb.
GetInterfaceType() const476 int MultiVerNaturalStore::GetInterfaceType() const
477 {
478     return SYNC_MVD;
479 }
480 
481 // Get the interface ref-count, in order to access asynchronously.
IncRefCount()482 void MultiVerNaturalStore::IncRefCount()
483 {
484     IncObjRef(this);
485 }
486 
487 // Drop the interface ref-count.
DecRefCount()488 void MultiVerNaturalStore::DecRefCount()
489 {
490     DecObjRef(this);
491 }
492 
493 // Get the identifier of this kvdb.
GetIdentifier() const494 std::vector<uint8_t> MultiVerNaturalStore::GetIdentifier() const
495 {
496     std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
497     std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
498     return identifierVect;
499 }
500 
GetStringIdentifier() const501 std::string MultiVerNaturalStore::GetStringIdentifier() const
502 {
503     std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
504     std::vector<uint8_t> idVect(identifier.begin(), identifier.end());
505     return VEC_TO_STR(idVect);
506 }
507 
508 // Get the max timestamp of all entries in database.
GetMaxTimestamp(Timestamp & stamp) const509 void MultiVerNaturalStore::GetMaxTimestamp(Timestamp &stamp) const
510 {
511     std::lock_guard<std::mutex> lock(maxTimeMutex_);
512     stamp = maxRecordTimestamp_;
513 }
514 
SetMaxTimestamp(Timestamp stamp)515 void MultiVerNaturalStore::SetMaxTimestamp(Timestamp stamp)
516 {
517     std::lock_guard<std::mutex> lock(maxTimeMutex_);
518     maxRecordTimestamp_ = (stamp > maxRecordTimestamp_) ? stamp : maxRecordTimestamp_;
519 }
520 
521 // Get meta data associated with the given key.
GetMetaData(const Key & key,Value & value) const522 int MultiVerNaturalStore::GetMetaData(const Key &key, Value &value) const
523 {
524     int errCode = E_OK;
525     auto handle = GetHandle(false, errCode);
526     if (handle == nullptr) {
527         return errCode;
528     }
529 
530     errCode = handle->GetMetaData(key, value);
531     ReleaseHandle(handle);
532     return errCode;
533 }
534 
535 // Put meta data as a key-value entry.
PutMetaData(const Key & key,const Value & value)536 int MultiVerNaturalStore::PutMetaData(const Key &key, const Value &value)
537 {
538     int errCode = E_OK;
539     auto handle = GetHandle(true, errCode);
540     if (handle == nullptr) {
541         return errCode;
542     }
543 
544     errCode = handle->PutMetaData(key, value);
545     ReleaseHandle(handle);
546     return errCode;
547 }
548 
DeleteMetaData(const std::vector<Key> & keys)549 int MultiVerNaturalStore::DeleteMetaData(const std::vector<Key> &keys)
550 {
551     return -E_NOT_SUPPORT;
552 }
553 
554 // Get all meta data keys.
GetAllMetaKeys(std::vector<Key> & keys) const555 int MultiVerNaturalStore::GetAllMetaKeys(std::vector<Key> &keys) const
556 {
557     return E_OK;
558 }
559 
IsCommitExisted(const MultiVerCommitNode & commit) const560 bool MultiVerNaturalStore::IsCommitExisted(const MultiVerCommitNode &commit) const
561 {
562     int errCode = E_OK;
563     auto handle = GetHandle(false, errCode);
564     if (handle == nullptr) {
565         return false;
566     }
567 
568     bool result = handle->IsCommitExisted(commit, errCode);
569     ReleaseHandle(handle);
570     return result;
571 }
572 
GetDeviceLatestCommit(std::map<std::string,MultiVerCommitNode> & commitMap) const573 int MultiVerNaturalStore::GetDeviceLatestCommit(std::map<std::string, MultiVerCommitNode> &commitMap) const
574 {
575     int errCode = E_OK;
576     auto handle = GetHandle(false, errCode);
577     if (handle == nullptr) {
578         return -E_BUSY;
579     }
580 
581     errCode = handle->GetDeviceLatestCommit(commitMap);
582     ReleaseHandle(handle);
583     return errCode;
584 }
585 
GetCommitTree(const std::map<std::string,MultiVerCommitNode> & commitMap,std::vector<MultiVerCommitNode> & commits) const586 int MultiVerNaturalStore::GetCommitTree(const std::map<std::string, MultiVerCommitNode> &commitMap,
587     std::vector<MultiVerCommitNode> &commits) const
588 {
589     int errCode = E_OK;
590     auto handle = GetHandle(false, errCode);
591     if (handle == nullptr) {
592         return -E_BUSY;
593     }
594 
595     errCode = handle->GetCommitTree(commitMap, commits);
596     ReleaseHandle(handle);
597     return errCode;
598 }
599 
GetCommitData(const MultiVerCommitNode & commit,std::vector<MultiVerKvEntry * > & entries) const600 int MultiVerNaturalStore::GetCommitData(const MultiVerCommitNode &commit, std::vector<MultiVerKvEntry *> &entries) const
601 {
602     int errCode = E_OK;
603     auto handle = GetHandle(false, errCode);
604     if (handle == nullptr) {
605         return -E_BUSY;
606     }
607 
608     errCode = handle->GetCommitData(commit, entries);
609     ReleaseHandle(handle);
610     return errCode;
611 }
612 
CreateKvEntry(const std::vector<uint8_t> & data)613 MultiVerKvEntry *MultiVerNaturalStore::CreateKvEntry(const std::vector<uint8_t> &data)
614 {
615     auto kvEntry = new (std::nothrow) GenericMultiVerKvEntry;
616     if (kvEntry == nullptr) {
617         return nullptr;
618     }
619 
620     int errCode = kvEntry->DeSerialData(data);
621     if (errCode != E_OK) {
622         LOGE("deserialize data into kv entry failed:%d", errCode);
623         delete kvEntry;
624         kvEntry = nullptr;
625     }
626     return kvEntry;
627 }
628 
ReleaseKvEntry(const MultiVerKvEntry * entry)629 void MultiVerNaturalStore::ReleaseKvEntry(const MultiVerKvEntry *entry)
630 {
631     if (entry != nullptr) {
632         delete entry;
633         entry = nullptr;
634     }
635 }
636 
IsValueSliceExisted(const ValueSliceHash & value) const637 bool MultiVerNaturalStore::IsValueSliceExisted(const ValueSliceHash &value) const
638 {
639     int errCode = E_OK;
640     auto handle = GetHandle(false, errCode);
641     if (handle == nullptr) {
642         return false;
643     }
644 
645     bool result = handle->IsValueSliceExisted(value, errCode);
646     ReleaseHandle(handle);
647     return result;
648 }
649 
GetValueSlice(const ValueSliceHash & hashValue,ValueSlice & sliceValue) const650 int MultiVerNaturalStore::GetValueSlice(const ValueSliceHash &hashValue, ValueSlice &sliceValue) const
651 {
652     int errCode = E_OK;
653     auto handle = GetHandle(false, errCode);
654     if (handle == nullptr) {
655         return -E_BUSY;
656     }
657 
658     errCode = handle->GetValueSlice(hashValue, sliceValue);
659     ReleaseHandle(handle);
660     return errCode;
661 }
662 
PutValueSlice(const ValueSliceHash & hashValue,const ValueSlice & sliceValue) const663 int MultiVerNaturalStore::PutValueSlice(const ValueSliceHash &hashValue, const ValueSlice &sliceValue) const
664 {
665     int errCode = E_OK;
666     auto handle = GetHandle(true, errCode);
667     if (handle == nullptr) {
668         return -E_BUSY;
669     }
670 
671     errCode = handle->PutValueSlice(hashValue, sliceValue, false);
672     ReleaseHandle(handle);
673     return errCode;
674 }
675 
PutCommitData(const MultiVerCommitNode & commit,const std::vector<MultiVerKvEntry * > & entries,const std::string & deviceName)676 int MultiVerNaturalStore::PutCommitData(const MultiVerCommitNode &commit, const std::vector<MultiVerKvEntry *> &entries,
677     const std::string &deviceName)
678 {
679     int errCode = E_OK;
680     auto handle = GetHandle(true, errCode);
681     if (handle == nullptr) {
682         return -E_BUSY;
683     }
684 
685     errCode = handle->PutCommitData(commit, entries, deviceName);
686     ReleaseHandle(handle);
687     return errCode;
688 }
689 
MergeSyncCommit(const MultiVerCommitNode & commit,const std::vector<MultiVerCommitNode> & commits)690 int MultiVerNaturalStore::MergeSyncCommit(const MultiVerCommitNode &commit,
691     const std::vector<MultiVerCommitNode> &commits)
692 {
693     int errCode = E_OK;
694     auto handle = GetHandle(true, errCode);
695     if (handle == nullptr) {
696         return -E_BUSY;
697     }
698 
699     errCode = handle->MergeSyncCommit(commit, commits);
700     ReleaseHandle(handle);
701     return errCode;
702 }
703 
NotifyStartSyncOperation()704 void MultiVerNaturalStore::NotifyStartSyncOperation()
705 {
706     shadowTrimmer_.Pause(GetStringIdentifier());
707 }
708 
NotifyFinishSyncOperation()709 void MultiVerNaturalStore::NotifyFinishSyncOperation()
710 {
711     shadowTrimmer_.Continue(GetStringIdentifier(), true);
712 }
713 
TransferSyncCommitDevInfo(MultiVerCommitNode & commit,const std::string & devId,bool isSyncedIn) const714 int MultiVerNaturalStore::TransferSyncCommitDevInfo(MultiVerCommitNode &commit, const std::string &devId,
715     bool isSyncedIn) const
716 {
717     std::string hashDevId = DBCommon::TransferHashString(devId);
718     if (isSyncedIn) {
719         // The size of the device info must be hash_size + tag_size;
720         if (commit.deviceInfo.size() == hashDevId.size() + MULTI_VER_TAG_SIZE) {
721             // If the hash device info is matched with the local, just remove the hash device info.
722             if (commit.deviceInfo.compare(0, hashDevId.size(), hashDevId) == 0) {
723                 commit.deviceInfo = commit.deviceInfo.substr(hashDevId.size(), MULTI_VER_TAG_SIZE);
724             }
725             return E_OK;
726         }
727         LOGE("Unexpected dev info for sync in:%zu", commit.deviceInfo.size());
728         return -E_UNEXPECTED_DATA;
729     } else {
730         // If the device info only contains the tag info, it must be local node.
731         if (commit.deviceInfo.size() == MULTI_VER_TAG_SIZE) {
732             commit.deviceInfo.insert(0, hashDevId);
733         } else if (commit.deviceInfo.size() != hashDevId.size() + MULTI_VER_TAG_SIZE) {
734             LOGE("Unexpected dev info for sync out:%zu", commit.deviceInfo.size());
735             return -E_UNEXPECTED_DATA;
736         }
737         return E_OK;
738     }
739 }
740 
Rekey(const CipherPassword & passwd)741 int MultiVerNaturalStore::Rekey(const CipherPassword &passwd)
742 {
743     if (multiVerEngine_ == nullptr) {
744         return -E_INVALID_DB;
745     }
746     int errCode = multiVerEngine_->TryToDisable(false, OperatePerm::REKEY_MONOPOLIZE_PERM);
747     if (errCode != E_OK) {
748         return errCode;
749     }
750     StopSyncer();
751     shadowTrimmer_.Pause(GetStringIdentifier());
752     errCode = multiVerEngine_->TryToDisable(true, OperatePerm::REKEY_MONOPOLIZE_PERM);
753     if (errCode != E_OK) {
754         multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
755         shadowTrimmer_.Continue(GetStringIdentifier(), true);
756         StartSyncer();
757         return errCode;
758     }
759 
760     std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
761         commitHistory_, multiVerKvStorage_);
762     errCode = operation->Rekey(passwd);
763 
764     multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
765     shadowTrimmer_.Continue(GetStringIdentifier(), true);
766     StartSyncer();
767 
768     return errCode;
769 }
770 
Export(const std::string & filePath,const CipherPassword & passwd)771 int MultiVerNaturalStore::Export(const std::string &filePath, const CipherPassword &passwd)
772 {
773     if (multiVerEngine_ == nullptr) {
774         return -E_INVALID_DB;
775     }
776     std::string localDev;
777     int errCode = GetLocalIdentity(localDev);
778     if (errCode != E_OK) {
779         LOGE("Failed to GetLocalIdentity!");
780     }
781     // Exclusively write resources
782     auto handle = GetHandle(true, errCode);
783     if (handle == nullptr) {
784         return errCode;
785     }
786 
787     std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
788         commitHistory_, multiVerKvStorage_);
789     operation->SetLocalDevId(localDev);
790     errCode = operation->Export(filePath, passwd);
791 
792     ReleaseHandle(handle);
793 
794     return errCode;
795 }
796 
Import(const std::string & filePath,const CipherPassword & passwd)797 int MultiVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd)
798 {
799     if (multiVerEngine_ == nullptr) {
800         return -E_INVALID_DB;
801     }
802     std::string localDev;
803     int errCode = GetLocalIdentity(localDev);
804     if (errCode != E_OK) {
805         LOGE("Failed to get the local identity!");
806         localDev.resize(0);
807     }
808     errCode = multiVerEngine_->TryToDisable(false, OperatePerm::IMPORT_MONOPOLIZE_PERM);
809     if (errCode != E_OK) {
810         return errCode;
811     }
812     StopSyncer();
813     shadowTrimmer_.Abort(GetStringIdentifier());
814     std::unique_ptr<MultiVerDatabaseOper> operation;
815     errCode = multiVerEngine_->TryToDisable(true, OperatePerm::IMPORT_MONOPOLIZE_PERM);
816     if (errCode != E_OK) {
817         goto END;
818     }
819     operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_, commitHistory_, multiVerKvStorage_);
820     operation->SetLocalDevId(localDev);
821     errCode = operation->Import(filePath, passwd);
822 END:
823     multiVerEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
824     shadowTrimmer_.Launch(GetStringIdentifier(), trimmerImpl_);
825     StartSyncer();
826     return errCode;
827 }
828 
GetCurrentTimestamp()829 uint64_t MultiVerNaturalStore::GetCurrentTimestamp()
830 {
831     return GetTimestamp();
832 }
833 
GetDiffEntries(const CommitID & begin,const CommitID & end,MultiVerDiffData & data) const834 int MultiVerNaturalStore::GetDiffEntries(const CommitID &begin, const CommitID &end, MultiVerDiffData &data) const
835 {
836     // Get one connection.
837     int errCode = E_OK;
838     auto handle = GetHandle(false, errCode);
839     if (handle == nullptr) {
840         return errCode;
841     }
842 
843     errCode = handle->GetDiffEntries(begin, end, data);
844     ReleaseHandle(handle);
845     return errCode;
846 }
847 
RecoverFromException()848 int MultiVerNaturalStore::RecoverFromException()
849 {
850     // Get the latest local version and the head node.
851     if (multiVerData_ == nullptr || commitHistory_ == nullptr) {
852         return -E_INVALID_DB;
853     }
854 
855     IKvDBMultiVerTransaction *transaction = nullptr;
856     int errCode = multiVerData_->StartWrite(KvDataType::KV_DATA_SYNC_P2P, transaction);
857     if (transaction == nullptr) {
858         goto END;
859     }
860     errCode = transaction->StartTransaction();
861     if (errCode != E_OK) {
862         goto END;
863     }
864 
865     errCode = CompareVerDataAndLog(transaction);
866     if (errCode != E_OK) {
867         LOGE("Compare the version data and log failed:%d", errCode);
868         transaction->RollBackTransaction();
869         goto END;
870     }
871     errCode = transaction->CommitTransaction();
872 END:
873     if (transaction != nullptr) {
874         multiVerData_->ReleaseTransaction(transaction);
875         transaction = nullptr;
876     }
877     return errCode;
878 }
879 
CompareVerDataAndLog(IKvDBMultiVerTransaction * transaction) const880 int MultiVerNaturalStore::CompareVerDataAndLog(IKvDBMultiVerTransaction *transaction) const
881 {
882     // Get the latest local version, we only care the local data.
883     Version maxLocalVersion = 0;
884     int errCode = transaction->GetMaxVersion(MultiVerDataType::NATIVE_TYPE, maxLocalVersion);
885     if (errCode != E_OK) {
886         return errCode;
887     }
888 
889     CommitID headerId = commitHistory_->GetHeader(errCode);
890     if (errCode != E_OK) {
891         return errCode;
892     }
893 
894     if (headerId.empty()) {
895         if (maxLocalVersion != 0) {
896             return transaction->ClearEntriesByVersion(maxLocalVersion);
897         }
898         return E_OK;
899     }
900 
901     IKvDBCommit *commitHead = commitHistory_->GetCommit(headerId, errCode);
902     if (commitHead == nullptr) {
903         return errCode;
904     }
905 
906     // compare the version
907     if (commitHead->GetCommitVersion() < maxLocalVersion) {
908         LOGD("Delete entries");
909         errCode = transaction->ClearEntriesByVersion(maxLocalVersion);
910     } else {
911         errCode = E_OK;
912     }
913 
914     commitHistory_->ReleaseCommit(commitHead);
915     commitHead = nullptr;
916     return errCode;
917 }
918 
GetMaxCommitVersion() const919 Version MultiVerNaturalStore::GetMaxCommitVersion() const
920 {
921     return maxCommitVersion_;
922 }
923 
SetMaxCommitVersion(const Version & version)924 void MultiVerNaturalStore::SetMaxCommitVersion(const Version &version)
925 {
926     maxCommitVersion_ = (version > maxCommitVersion_) ? version : maxCommitVersion_;
927 }
928 
GetHandle(bool isWrite,int & errCode,bool isTrimming,OperatePerm perm) const929 MultiVerStorageExecutor *MultiVerNaturalStore::GetHandle(bool isWrite, int &errCode,
930     bool isTrimming, OperatePerm perm) const
931 {
932     if (multiVerEngine_ == nullptr) {
933         errCode = -E_INVALID_DB;
934         return nullptr;
935     }
936 
937     if (isWrite && !isTrimming) {
938         // stop the trimming
939         shadowTrimmer_.Pause(GetStringIdentifier());
940     }
941     StorageExecutor *handle = nullptr;
942     if (isTrimming) {
943         handle = multiVerEngine_->FindExecutor(isWrite, OperatePerm::NORMAL_PERM, errCode, 0);
944     } else {
945         handle = multiVerEngine_->FindExecutor(isWrite, perm, errCode);
946     }
947 
948     if (handle == nullptr) {
949         if (isWrite && !isTrimming) {
950             // restart the trimming
951             shadowTrimmer_.Continue(GetStringIdentifier(), false);
952         }
953     } else {
954         if (!handle->GetWritable() && isTrimming) {
955             static_cast<MultiVerStorageExecutor *>(handle)->InitCurrentReadVersion();
956         }
957     }
958     return static_cast<MultiVerStorageExecutor *>(handle);
959 }
960 
ReleaseHandle(MultiVerStorageExecutor * & handle,bool isTrimming) const961 void MultiVerNaturalStore::ReleaseHandle(MultiVerStorageExecutor *&handle, bool isTrimming) const
962 {
963     if (multiVerEngine_ == nullptr || handle == nullptr) {
964         return;
965     }
966     bool isCorrupted = handle->GetCorruptedStatus();
967     bool isWrite = handle->GetWritable();
968     StorageExecutor *databaseHandle = handle;
969     multiVerEngine_->Recycle(databaseHandle);
970     handle = nullptr;
971     if (isCorrupted) {
972         CorruptNotify();
973     }
974     if (isWrite && !isTrimming) {
975         // restart the trimming.
976         LOGI("Release handle and continue vacuum data!");
977         shadowTrimmer_.Continue(GetStringIdentifier(), true);
978     }
979 }
980 
InitStorageContext(bool isChangeTag)981 int MultiVerNaturalStore::InitStorageContext(bool isChangeTag)
982 {
983     int errCode = InitStorageContextVersion(isChangeTag);
984     if (errCode != E_OK) {
985         return errCode;
986     }
987 
988     maxCommitVersion_ = commitHistory_->GetMaxCommitVersion(errCode);
989     if (errCode != E_OK) {
990         LOGE("Get the max commit version failed:%d", errCode);
991     }
992     return errCode;
993 }
994 
InitStorageContextVersion(bool isChangeTag)995 int MultiVerNaturalStore::InitStorageContextVersion(bool isChangeTag)
996 {
997     std::string verFilePath;
998     int errCode = GetVersionFilePath(MyProp(), verFilePath);
999     if (errCode != E_OK) {
1000         return errCode;
1001     }
1002 
1003     if (!OS::CheckPathExistence(verFilePath)) {
1004         return CreateNewVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_);
1005     }
1006     if (isChangeTag) {
1007         return ChangeVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_, isChangeTag);
1008     }
1009     uint32_t version = 0;
1010     return GetVersionAndTag(verFilePath, version, branchTag_);
1011 }
1012 
GetCurrentTag(std::vector<uint8_t> & tag) const1013 void MultiVerNaturalStore::GetCurrentTag(std::vector<uint8_t> &tag) const
1014 {
1015     tag = branchTag_;
1016 }
1017 
AddVersionConstraintToList(Version version)1018 void MultiVerNaturalStore::AddVersionConstraintToList(Version version)
1019 {
1020     std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1021     versionConstraints_.insert(version);
1022 }
1023 
RemoveVersionConstraintFromList(Version version)1024 void MultiVerNaturalStore::RemoveVersionConstraintFromList(Version version)
1025 {
1026     std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1027     auto iter = versionConstraints_.find(version);
1028     if (iter != versionConstraints_.end()) {
1029         versionConstraints_.erase(iter);
1030         // Auto launch the vacuum.
1031         shadowTrimmer_.AutoRelaunchOnce(GetStringIdentifier());
1032     }
1033 }
1034 
GetMaxTrimmableVersion() const1035 Version MultiVerNaturalStore::GetMaxTrimmableVersion() const
1036 {
1037     std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1038     if (versionConstraints_.empty()) {
1039         return UINT64_MAX;
1040     }
1041     return *(versionConstraints_.begin());
1042 }
1043 
TransObserverTypeToRegisterFunctionType(int observerType,RegisterFuncType & type) const1044 int MultiVerNaturalStore::TransObserverTypeToRegisterFunctionType(int observerType, RegisterFuncType &type) const
1045 {
1046     if (observerType == static_cast<uint32_t>(NATURAL_STORE_COMMIT_EVENT)) {
1047         type = OBSERVER_MULTI_VERSION_NS_COMMIT_EVENT;
1048         return E_OK;
1049     }
1050     return -E_NOT_SUPPORT;
1051 }
1052 
GetDbProperties() const1053 const KvDBProperties &MultiVerNaturalStore::GetDbProperties() const
1054 {
1055     return GetMyProperties();
1056 }
1057 
RemoveKvDB(const KvDBProperties & properties)1058 int MultiVerNaturalStore::RemoveKvDB(const KvDBProperties &properties)
1059 {
1060     std::string storeOnlyDir;
1061     std::string storeDir;
1062     GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE, storeDir, storeOnlyDir);
1063     int errCodeVersion = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_DATA_STORE);
1064     int errCodeCommit = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_COMMIT_STORE);
1065     int errCodeValue = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_VALUE_STORE);
1066     int errCodeMeta = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_META_STORE);
1067     LOGD("Delete the versionStorage:%d, commitStorage:%d, valueStorage:%d, metaStorage:%d",
1068         errCodeVersion, errCodeCommit, errCodeValue, errCodeMeta);
1069     DBCommon::RemoveAllFilesOfDirectory(storeDir, true);
1070     DBCommon::RemoveAllFilesOfDirectory(storeOnlyDir, true);
1071     if (errCodeVersion == E_OK && errCodeCommit == E_OK) {
1072         return E_OK;
1073     }
1074     if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == -E_NOT_FOUND) {
1075         return -E_NOT_FOUND;
1076     }
1077     if (errCodeVersion == E_OK && errCodeCommit == -E_NOT_FOUND) {
1078         return E_OK;
1079     }
1080     if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == E_OK) {
1081         return E_OK;
1082     }
1083     return errCodeCommit;
1084 }
1085 
GetKvDBSize(const KvDBProperties & properties,uint64_t & size) const1086 int MultiVerNaturalStore::GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const
1087 {
1088     std::string storeOnlyDir;
1089     std::string storeDir;
1090     GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE, storeDir, storeOnlyDir);
1091 
1092     std::vector<std::string> storageNames = {
1093         DBConstant::MULTI_VER_DATA_STORE,
1094         DBConstant::MULTI_VER_COMMIT_STORE,
1095         DBConstant::MULTI_VER_VALUE_STORE,
1096         DBConstant::MULTI_VER_META_STORE
1097     };
1098 
1099     // there only calculate db related file size
1100     for (const auto &storageName : storageNames) {
1101         uint64_t dbSize = 0;
1102         int errCode = KvDBUtils::GetKvDbSize(storeDir, storeOnlyDir, storageName, dbSize);
1103         if (errCode == E_OK) {
1104             size += dbSize;
1105             continue;
1106         }
1107 
1108         if (errCode == -E_NOT_FOUND) {
1109             return -E_NOT_FOUND;
1110         }
1111 
1112         size = 0;
1113         return errCode;
1114     }
1115     return E_OK;
1116 }
1117 
GetDbPropertyForUpdate()1118 KvDBProperties &MultiVerNaturalStore::GetDbPropertyForUpdate()
1119 {
1120     return MyProp();
1121 }
1122 
CheckVersion(const KvDBProperties & kvDBProp) const1123 int MultiVerNaturalStore::CheckVersion(const KvDBProperties &kvDBProp) const
1124 {
1125     LOGD("[MultiVerStore][CheckVer] Current Overall Version: %u.", MULTI_VER_STORE_VERSION_CURRENT);
1126     bool isVerFileExist = false;
1127     int errCode = CheckOverallVersionViaVersionFile(kvDBProp, isVerFileExist);
1128     if (errCode != E_OK) {
1129         return errCode;
1130     }
1131     bool isSubStorageExist = false;
1132     errCode = CheckSubStorageVersion(kvDBProp, isSubStorageExist);
1133     if (errCode != E_OK) {
1134         return errCode;
1135     }
1136     if (isVerFileExist != isSubStorageExist) {
1137         LOGW("[MultiVerStore][CheckVer] Detect File Lost, isVerFileExist=%d, isSubStorageExist=%d.",
1138             isVerFileExist, isSubStorageExist);
1139     }
1140     return E_OK;
1141 }
1142 
CheckOverallVersionViaVersionFile(const KvDBProperties & kvDBProp,bool & isVerFileExist) const1143 int MultiVerNaturalStore::CheckOverallVersionViaVersionFile(const KvDBProperties &kvDBProp, bool &isVerFileExist) const
1144 {
1145     std::string verFilePath;
1146     int errCode = GetVersionFilePath(kvDBProp, verFilePath);
1147     if (errCode != E_OK) {
1148         return errCode;
1149     }
1150     // Absent of version file may because: 1: Newly created database; 2: An already created database lost version file.
1151     // In both case, we returned E_OK here. After each sub storage be successfully open and upgrade, create verFile.
1152     if (!OS::CheckPathExistence(verFilePath)) {
1153         LOGD("[MultiVerStore][CheckOverVer] No Version File.");
1154         isVerFileExist = false;
1155         return E_OK;
1156     }
1157     isVerFileExist = true;
1158 
1159     uint32_t overallVersion = 0;
1160     std::vector<uint8_t> branchTagInVerFile;
1161     errCode = GetVersionAndTag(verFilePath, overallVersion, branchTagInVerFile);
1162     if (errCode != E_OK) {
1163         LOGE("[MultiVerStore][CheckOverVer] GetVersionAndTag fail, errCode=%d.", errCode);
1164         return errCode;
1165     }
1166     LOGD("[MultiVerStore][CheckOverVer] overallVersion=%u, tag=%s.", overallVersion, VEC_TO_STR(branchTagInVerFile));
1167     if (overallVersion > MULTI_VER_STORE_VERSION_CURRENT) {
1168         LOGE("[MultiVerStore][CheckOverVer] Version Not Support!");
1169         return -E_VERSION_NOT_SUPPORT;
1170     }
1171     return E_OK;
1172 }
1173 
GetVersionFilePath(const KvDBProperties & kvDBProp,std::string & outPath) const1174 int MultiVerNaturalStore::GetVersionFilePath(const KvDBProperties &kvDBProp, std::string &outPath) const
1175 {
1176     std::string verFiledir;
1177     int errCode = GetWorkDir(kvDBProp, verFiledir);
1178     if (errCode != E_OK) {
1179         LOGE("[MultiVerStore][GetVerFilePath] GetWorkDir fail, errCode=%d", errCode);
1180         return errCode;
1181     }
1182     outPath = verFiledir + "/" + DBConstant::MULTI_SUB_DIR + "/version";
1183     return E_OK;
1184 }
1185 
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const1186 int MultiVerNaturalStore::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
1187 {
1188     (void)keyPrefix;
1189     return -E_NOT_SUPPORT;
1190 }
1191 
SetDataInterceptor(const PushDataInterceptor & interceptor)1192 void MultiVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor)
1193 {
1194     (void)interceptor;
1195     return;
1196 }
1197 
1198 DEFINE_OBJECT_TAG_FACILITIES(MultiVerNaturalStore)
1199 } // namespace DistributedDB
1200 #endif
1201