• 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 KV_DB_MANAGER_H
17 #define KV_DB_MANAGER_H
18 
19 #include <string>
20 #include <map>
21 #include <mutex>
22 #include <set>
23 #include <condition_variable>
24 
25 #include "db_errno.h"
26 #include "ikvdb.h"
27 #include "ikvdb_factory.h"
28 #include "platform_specific.h"
29 
30 namespace DistributedDB {
31 class KvDBManager final {
32 public:
33     // used to generate process label
34     static const std::string PROCESS_LABEL_CONNECTOR;
35 
36     // used to open a kvdb with the given property
37     static IKvDB *OpenDatabase(const KvDBProperties &property, int &errCode);
38 
39     // used to open a kvdb with the given property
40     static IKvDBConnection *GetDatabaseConnection(const KvDBProperties &property, int &errCode,
41         bool isNeedIfOpened = true);
42 
43     // used to close the connection.
44     static int ReleaseDatabaseConnection(IKvDBConnection *connection);
45 
46     // used to delete a kvdb with the given property.
47     static int RemoveDatabase(const KvDBProperties &property);
48 
49     // Used to set the process userid and appid
50     static int SetProcessLabel(const std::string &appId, const std::string &userId);
51 
52     static int CalculateKvStoreSize(const KvDBProperties &property, uint64_t &size);
53 
54     // used to restore the sync module of the store.
55     static void RestoreSyncableKvStore();
56 
57     // used to set the corruption handler.
58     static void SetDatabaseCorruptionHandler(const KvStoreCorruptionHandler &handler);
59 
60     // Attention. After call FindKvDB and kvdb is not null, you need to call DecObjRef.
61     IKvDB* FindKvDB(const std::string &identifier) const;
62 
63     // Get a KvDBManager instance, Singleton mode
64     static KvDBManager *GetInstance();
65 private:
66     // Generate a KvDB unique Identifier
67     static std::string GenerateKvDBIdentifier(const KvDBProperties &property);
68 
69     // used to judge Db opened, can not remove Db file
70     static int CheckDatabaseFileStatus(const KvDBProperties &properties);
71 
72     IKvDB *OpenNewDatabase(const KvDBProperties &property, int &errCode);
73 
74     // Save to IKvDB to the global map
75     IKvDB *SaveKvDBToCache(IKvDB *kvDB);
76 
77     // Get IKvdb From global map
78     IKvDB *FindAndGetKvDBFromCache(const KvDBProperties &property, int &errCode) const;
79 
80     // Get IKvdb From global map
81     void RemoveKvDBFromCache(const IKvDB *kvDB);
82 
83     // Find a IKvdb From the given cache. the IKvDB will IncObjRef if found.
84     IKvDB *FindKvDBFromCache(const KvDBProperties &property,
85         const std::map<std::string, IKvDB *> &cache, bool isNeedCheckPasswd, int &errCode) const;
86 
87     bool IsOpenMemoryDb(const KvDBProperties &properties, const std::map<std::string, IKvDB *> &cache) const;
88 
89     void RestoreSyncerOfAllKvStore();
90 
91     void SetAllDatabaseCorruptionHander(const KvStoreCorruptionHandler &handler);
92 
93     IKvDB *CreateDataBase(const KvDBProperties &property, int &errCode);
94 
95     IKvDB *GetDataBase(const KvDBProperties &property, int &errCode, bool isNeedIfOpened);
96 
97     void DataBaseCorruptNotify(const std::string &appId, const std::string &userId, const std::string &storeId);
98 
99     void DataBaseCorruptNotifyAsync(const std::string &appId, const std::string &userId, const std::string &storeId);
100 
101     void EnterDBOpenCloseProcess(const std::string &identifier);
102 
103     void ExitDBOpenCloseProcess(const std::string &identifier);
104 
105     void SetCorruptHandlerForDatabases(const std::map<std::string, IKvDB *> &kvDBMap);
106 
107     // Compare two schema objects and return true if both are empty,
108     // or both are not empty and the schemas are equal, otherwise return false.
109     static bool CompareSchemaObject(const SchemaObject &newSchema, const SchemaObject &oldSchema);
110 
111     // check schema is valid
112     static int CheckSchema(const IKvDB *kvDB, const KvDBProperties &properties);
113 
114     static int ExecuteRemoveDatabase(const KvDBProperties &properties);
115 
116     static void RemoveDBDirectory(const KvDBProperties &properties);
117 
118     int CheckKvDBProperties(const IKvDB *kvDB, const KvDBProperties &properties,
119         bool isNeedCheckPasswd) const;
120 
121     IKvDB *GetKvDBFromCacheByIdentify(const std::string &identifier, const std::map<std::string, IKvDB *> &cache) const;
122 
123     static int CheckRemoveStateAndRetry(const KvDBProperties &property);
124 
125     static int TryLockDB(const KvDBProperties &kvDBProp, int retryTimes);
126     static int UnlockDB(const KvDBProperties &kvDBProp);
127 
128     static std::atomic<KvDBManager *> instance_;
129     static std::mutex kvDBLock_;
130     static std::mutex instanceLock_;
131     static std::map<std::string, OS::FileHandle> locks_;
132 
133     std::map<std::string, IKvDB *> localKvDBs_;
134     std::map<std::string, IKvDB *> multiVerNaturalStores_;
135     std::map<std::string, IKvDB *> singleVerNaturalStores_;
136 
137     std::mutex corruptMutex_;
138     std::mutex kvDBOpenMutex_;
139     std::condition_variable kvDBOpenCondition_;
140     std::set<std::string> kvDBOpenSet_;
141     KvStoreCorruptionHandler corruptHandler_;
142 };
143 } // namespace DistributedDB
144 
145 #endif // KV_DB_MANAGER_H
146