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 66 // Dump all db message in cache 67 void Dump(int fd); 68 private: 69 // Generate a KvDB unique Identifier 70 static std::string GenerateKvDBIdentifier(const KvDBProperties &property); 71 72 // used to judge Db opened, can not remove Db file 73 static int CheckDatabaseFileStatus(const KvDBProperties &properties); 74 75 IKvDB *OpenNewDatabase(const KvDBProperties &property, int &errCode); 76 77 // Save to IKvDB to the global map 78 IKvDB *SaveKvDBToCache(IKvDB *kvDB); 79 80 // Get IKvdb From global map 81 IKvDB *FindAndGetKvDBFromCache(const KvDBProperties &property, int &errCode) const; 82 83 // Get IKvdb From global map 84 void RemoveKvDBFromCache(const IKvDB *kvDB); 85 86 // Find a IKvdb From the given cache. the IKvDB will IncObjRef if found. 87 IKvDB *FindKvDBFromCache(const KvDBProperties &property, 88 const std::map<std::string, IKvDB *> &cache, bool isNeedCheckPasswd, int &errCode) const; 89 90 bool IsOpenMemoryDb(const KvDBProperties &properties, const std::map<std::string, IKvDB *> &cache) const; 91 92 void RestoreSyncerOfAllKvStore(); 93 94 void SetAllDatabaseCorruptionHander(const KvStoreCorruptionHandler &handler); 95 96 IKvDB *CreateDataBase(const KvDBProperties &property, int &errCode); 97 98 IKvDB *GetDataBase(const KvDBProperties &property, int &errCode, bool isNeedIfOpened); 99 100 void DataBaseCorruptNotify(const std::string &appId, const std::string &userId, const std::string &storeId); 101 102 void DataBaseCorruptNotifyAsync(const std::string &appId, const std::string &userId, const std::string &storeId); 103 104 void EnterDBOpenCloseProcess(const std::string &identifier); 105 106 void ExitDBOpenCloseProcess(const std::string &identifier); 107 108 void SetCorruptHandlerForDatabases(const std::map<std::string, IKvDB *> &kvDBMap); 109 110 // Compare two schema objects and return true if both are empty, 111 // or both are not empty and the schemas are equal, otherwise return false. 112 static bool CompareSchemaObject(const SchemaObject &newSchema, const SchemaObject &oldSchema); 113 114 // check schema is valid 115 static int CheckSchema(const IKvDB *kvDB, const KvDBProperties &properties); 116 117 static int ExecuteRemoveDatabase(const KvDBProperties &properties); 118 119 static void RemoveDBDirectory(const KvDBProperties &properties); 120 121 int CheckKvDBProperties(const IKvDB *kvDB, const KvDBProperties &properties, 122 bool isNeedCheckPasswd) const; 123 124 IKvDB *GetKvDBFromCacheByIdentify(const std::string &identifier, const std::map<std::string, IKvDB *> &cache) const; 125 126 static int CheckRemoveStateAndRetry(const KvDBProperties &property); 127 128 static int TryLockDB(const KvDBProperties &kvDBProp, int retryTimes); 129 static int UnlockDB(const KvDBProperties &kvDBProp); 130 131 static bool CheckOpenDBOptionWithCached(const KvDBProperties &properties, IKvDB *kvdb); 132 133 static std::atomic<KvDBManager *> instance_; 134 static std::mutex kvDBLock_; 135 static std::mutex instanceLock_; 136 137 static std::mutex fileHandleMutex_; 138 static std::map<std::string, OS::FileHandle *> locks_; 139 140 std::map<std::string, IKvDB *> localKvDBs_; 141 std::map<std::string, IKvDB *> multiVerNaturalStores_; 142 std::map<std::string, IKvDB *> singleVerNaturalStores_; 143 144 std::mutex corruptMutex_; 145 std::mutex kvDBOpenMutex_; 146 std::condition_variable kvDBOpenCondition_; 147 std::set<std::string> kvDBOpenSet_; 148 KvStoreCorruptionHandler corruptHandler_; 149 }; 150 } // namespace DistributedDB 151 152 #endif // KV_DB_MANAGER_H 153