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