1 /* 2 * Copyright (c) 2022 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 NATIVE_RDB_SQLITE_CONNECTION_POOL_H 17 #define NATIVE_RDB_SQLITE_CONNECTION_POOL_H 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <iostream> 22 #include <iterator> 23 #include <list> 24 #include <memory> 25 #include <mutex> 26 #include <sstream> 27 #include <stack> 28 #include <vector> 29 30 #include "base_transaction.h" 31 #include "connection.h" 32 #include "rdb_common.h" 33 #include "rdb_store_config.h" 34 #include "delay_actuator.h" 35 namespace OHOS { 36 class ExecutorPool; 37 namespace NativeRdb { 38 class ConnectionPool : public std::enable_shared_from_this<ConnectionPool> { 39 public: 40 using SharedConn = std::shared_ptr<Connection>; 41 using SharedConns = std::vector<SharedConn>; 42 static constexpr std::chrono::milliseconds INVALID_TIME = std::chrono::milliseconds(0); 43 static std::shared_ptr<ConnectionPool> Create(const RdbStoreConfig &config, int &errCode); 44 ~ConnectionPool(); 45 static std::pair<RebuiltType, std::shared_ptr<ConnectionPool>> HandleDataCorruption( 46 const RdbStoreConfig &storeConfig, int &errCode); 47 std::pair<int32_t, std::shared_ptr<Connection>> CreateTransConn(bool limited = true); 48 SharedConn AcquireConnection(bool isReadOnly); 49 SharedConn Acquire(bool isReadOnly, std::chrono::milliseconds ms = INVALID_TIME); 50 // this interface is only provided for resultSet 51 SharedConn AcquireRef(bool isReadOnly, std::chrono::milliseconds ms = INVALID_TIME); 52 std::pair<SharedConn, SharedConns> AcquireAll(int32_t time); 53 std::pair<int32_t, SharedConn> DisableWal(); 54 int32_t EnableWal(); 55 int32_t Dump(bool isWriter, const char *header); 56 57 int RestartConns(); 58 int ReopenConns(); 59 int ConfigLocale(const std::string &localeStr); 60 int ChangeDbFileForRestore(const std::string &newPath, const std::string &backupPath, 61 const std::vector<uint8_t> &newKey, std::shared_ptr<SlaveStatus> slaveStatus); 62 int Rekey(const RdbStoreConfig::CryptoParam &cryptoParam); 63 std::stack<BaseTransaction> &GetTransactionStack(); 64 std::mutex &GetTransactionStackMutex(); 65 int AcquireTransaction(); 66 void ReleaseTransaction(); 67 void CloseAllConnections(); 68 bool IsInTransaction(); 69 void SetInTransaction(bool isInTransaction); 70 71 private: 72 struct ConnNode { 73 bool using_ = false; 74 int32_t tid_ = 0; 75 int32_t id_ = 0; 76 std::chrono::steady_clock::time_point time_ = std::chrono::steady_clock::now(); 77 const std::shared_ptr<Connection> connect_; 78 79 explicit ConnNode(std::shared_ptr<Connection> conn); 80 std::shared_ptr<Connection> GetConnect(); 81 int64_t GetUsingTime() const; 82 bool IsWriter() const; 83 int32_t Unused(int32_t count, bool timeout); 84 bool IsRecyclable(); 85 }; 86 87 struct Container { 88 using Creator = std::function<std::pair<int32_t, std::shared_ptr<Connection>>()>; 89 static constexpr int32_t MAX_RIGHT = 0x4FFFFFFF; 90 static constexpr int32_t MIN_TRANS_ID = 10000; 91 bool disable_ = true; 92 int max_ = 0; 93 int total_ = 0; 94 int count_ = 0; 95 int32_t left_ = 0; 96 int32_t right_ = 0; 97 std::chrono::seconds timeout_; 98 std::list<std::shared_ptr<ConnNode>> nodes_; 99 std::list<std::weak_ptr<ConnNode>> details_; 100 std::mutex mutex_; 101 std::condition_variable cond_; 102 Creator creator_ = nullptr; 103 std::pair<int32_t, std::shared_ptr<ConnNode>> Initialize( 104 Creator creator, int32_t max, int32_t timeout, bool disable, bool acquire = false); 105 int32_t ConfigLocale(const std::string &locale); 106 std::pair<int, std::shared_ptr<ConnNode>> Acquire(std::chrono::milliseconds milliS); 107 std::pair<bool, std::list<std::shared_ptr<ConnNode>>> AcquireAll(std::chrono::milliseconds milliS); 108 std::pair<int32_t, std::shared_ptr<ConnNode>> Create(); 109 void InitMembers(Creator creator, int32_t max, int32_t timeout, bool disable); 110 111 void Disable(); 112 void Enable(); 113 int32_t Release(std::shared_ptr<ConnNode> node); 114 int32_t ReleaseTrans(std::shared_ptr<ConnNode> node); 115 int32_t Clear(); 116 bool IsFull(); 117 bool Empty(); 118 int32_t Dump(const char *header, int32_t count); 119 int32_t ClearUnusedTrans(std::shared_ptr<ConnectionPool> pool); 120 121 private: 122 int32_t ExtendNode(); 123 int32_t RelDetails(std::shared_ptr<ConnNode> node); 124 }; 125 126 explicit ConnectionPool(const RdbStoreConfig &storeConfig); 127 std::pair<int32_t, std::shared_ptr<Connection>> Init(bool isAttach = false, bool needWriter = false); 128 int32_t GetMaxReaders(const RdbStoreConfig &config); 129 std::shared_ptr<Connection> Convert2AutoConn(std::shared_ptr<ConnNode> node, bool isTrans = false); 130 void ReleaseNode(std::shared_ptr<ConnNode> node, bool reuse = true); 131 int RestoreByDbSqliteType(const std::string &newPath, const std::string &backupPath, 132 std::shared_ptr<SlaveStatus> slaveStatus); 133 int RestoreMasterDb(const std::string &newPath, const std::string &backupPath); 134 bool CheckIntegrity(const std::string &dbPath); 135 void DelayClearTrans(); 136 137 static constexpr uint32_t CHECK_POINT_INTERVAL = 5; // 5 min 138 static constexpr int LIMITATION = 1024; 139 static constexpr uint32_t ITER_V1 = 5000; 140 static constexpr uint32_t ITERS_COUNT = 2; 141 static constexpr uint32_t MAX_TRANS = 4; 142 static constexpr std::chrono::steady_clock::duration TRANS_CLEAR_INTERVAL = std::chrono::seconds(150); 143 static constexpr uint32_t FIRST_DELAY_INTERVAL = ActuatorBase::INVALID_INTERVAL; 144 static constexpr uint32_t MIN_EXECUTE_INTERVAL = ActuatorBase::INVALID_INTERVAL; 145 static constexpr uint32_t MAX_EXECUTE_INTERVAL = 30000; // 30000ms 146 std::shared_ptr<DelayActuator<std::vector<std::weak_ptr<ConnNode>>, 147 std::function<void(std::vector<std::weak_ptr<ConnNode>> &out, std::shared_ptr<ConnNode> &&input)>>> 148 clearActuator_; 149 const RdbStoreConfig &config_; 150 RdbStoreConfig attachConfig_; 151 Container writers_; 152 Container readers_; 153 Container trans_; 154 int32_t maxReader_ = 0; 155 156 std::stack<BaseTransaction> transactionStack_; 157 std::mutex transactionStackMutex_; 158 std::condition_variable transCondition_; 159 std::mutex transMutex_; 160 bool transactionUsed_; 161 bool isAttach_ = false; 162 std::atomic<bool> isInTransaction_ = false; 163 std::atomic<uint32_t> transCount_ = 0; 164 std::atomic<std::chrono::steady_clock::time_point> failedTime_; 165 }; 166 167 } // namespace NativeRdb 168 } // namespace OHOS 169 #endif 170