1 /*
2 * Copyright (c) 2023 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 #include "rd_single_ver_result_set.h"
16 #include "db_errno.h"
17 #include "grd_base/grd_db_api.h"
18 #include "grd_base/grd_resultset_api.h"
19 #include "log_print.h"
20 #include "rd_utils.h"
21 #include "sqlite_single_ver_storage_executor_sql.h"
22
23 namespace DistributedDB {
RdSingleVerResultSet(RdSingleVerNaturalStore * kvDB,const Key & key)24 RdSingleVerResultSet::RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &key)
25 : key_(key), kvDB_(kvDB)
26 {
27 kvScanMode_ = KV_SCAN_PREFIX;
28 }
29
RdSingleVerResultSet(RdSingleVerNaturalStore * kvDB,const Key & beginKey,const Key & endKey,GRD_KvScanModeE kvScanMode)30 RdSingleVerResultSet::RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &beginKey,
31 const Key &endKey, GRD_KvScanModeE kvScanMode)
32 : beginKey_(beginKey), endKey_(endKey), kvScanMode_(kvScanMode), kvDB_(kvDB) {}
33
~RdSingleVerResultSet()34 RdSingleVerResultSet::~RdSingleVerResultSet()
35 {
36 isOpen_ = false;
37 position_ = INIT_POSITION;
38 kvDB_ = nullptr;
39 handle_ = nullptr;
40 }
41
Open(bool isMemDb)42 int RdSingleVerResultSet::Open(bool isMemDb)
43 {
44 (void)isMemDb;
45 std::lock_guard<std::mutex> lockGuard(mutex_);
46 if (isOpen_) {
47 LOGW("[RdSinResSet] Not need to open result set again!");
48 return E_OK;
49 }
50 if (kvDB_ == nullptr) { // Unlikely
51 return -E_INVALID_ARGS;
52 }
53 if (kvScanMode_ >= KV_SCAN_BUTT) {
54 LOGE("[RdSinResSet] Open result scan mode is invalid.");
55 return -E_INVALID_ARGS;
56 }
57 int errCode = E_OK;
58 handle_ = kvDB_->GetHandle(false, errCode);
59 if (handle_ == nullptr) {
60 LOGE("[RdSinResSet] Get handle failed, errCode=%d.", errCode);
61 return errCode;
62 }
63 switch (kvScanMode_) {
64 case KV_SCAN_PREFIX: {
65 errCode = handle_->OpenResultSet(key_, kvScanMode_, &resultSet_);
66 break;
67 }
68 case KV_SCAN_RANGE: {
69 errCode = handle_->OpenResultSet(beginKey_, endKey_, &resultSet_);
70 break;
71 }
72 default:
73 return -E_INVALID_ARGS;
74 }
75 if (errCode != E_OK) {
76 LOGE("[RdSinResSet] open result set failed, %d.", errCode);
77 kvDB_->ReleaseHandle(handle_);
78 return errCode;
79 }
80 isOpen_ = true;
81 return E_OK;
82 }
83
Close()84 int RdSingleVerResultSet::Close()
85 {
86 std::lock_guard<std::mutex> lockGuard(mutex_);
87 int errCode = PreCheckResultSet();
88 if (errCode != E_OK) {
89 return errCode;
90 }
91
92 errCode = handle_->CloseResultSet(resultSet_);
93 if (errCode != E_OK) {
94 LOGE("[RdSinResSet] close rd result set failed, errCode=%d.", errCode);
95 kvDB_->ReleaseHandle(handle_);
96 return errCode;
97 }
98 kvDB_->ReleaseHandle(handle_);
99 isOpen_ = false;
100 position_ = INIT_POSITION;
101 return E_OK;
102 }
103
PreCheckResultSet() const104 int RdSingleVerResultSet::PreCheckResultSet() const
105 {
106 if (!isOpen_) {
107 LOGE("[RdSinResSet] Result set not open yet.");
108 return -E_RESULT_SET_STATUS_INVALID;
109 }
110 if (kvDB_ == nullptr) { // Unlikely
111 LOGE("[RdSinResSet] KvDB not set yet.");
112 return -E_INVALID_ARGS;
113 }
114
115 if (handle_ == nullptr) {
116 LOGE("[RdSinResSet] Handle not set yet.");
117 return -E_INVALID_ARGS;
118 }
119 return E_OK;
120 }
121
GetCount() const122 int RdSingleVerResultSet::GetCount() const
123 {
124 int errCode = PreCheckResultSet();
125 if (errCode != E_OK) {
126 return errCode;
127 }
128 int count = 0;
129 switch (kvScanMode_) {
130 case KV_SCAN_PREFIX: {
131 errCode = handle_->GetCount(key_, count, kvScanMode_);
132 break;
133 }
134 case KV_SCAN_RANGE: {
135 errCode = handle_->GetCount(beginKey_, endKey_, count, kvScanMode_);
136 break;
137 }
138 default:
139 return -E_INVALID_ARGS;
140 }
141 if (errCode != E_OK && errCode != -E_RESULT_SET_EMPTY) {
142 return errCode;
143 }
144 return count;
145 }
146
GetPosition() const147 int RdSingleVerResultSet::GetPosition() const
148 {
149 std::lock_guard<std::mutex> lockGuard(mutex_);
150 return position_;
151 }
152
Move(int offset) const153 int RdSingleVerResultSet::Move(int offset) const
154 {
155 std::lock_guard<std::mutex> lockGuard(mutex_);
156 int errCode = E_OK;
157 if (offset == 0) {
158 return errCode;
159 }
160
161 while (offset > 0) {
162 errCode = MoveToNext();
163 if (errCode != E_OK) {
164 if (errCode == -E_NOT_FOUND) {
165 LOGE("[RdSingleVerStorageExecutor] move offset: %d, out of bounds, position: %d", offset, position_);
166 return -E_INVALID_ARGS;
167 }
168 LOGE("[RdSinResSet] move by offset failed, errCode=%d, offset=%d", errCode, offset);
169 return errCode;
170 }
171 --offset;
172 }
173 while (offset < 0) {
174 errCode = MoveToPrev();
175 if (errCode != E_OK) {
176 if (errCode == -E_NOT_FOUND && offset <= 0) {
177 LOGE("[RdSingleVerStorageExecutor] move offset: %d, out of bounds, position: %d", offset, position_);
178 return -E_INVALID_ARGS;
179 }
180 LOGE("[RdSinResSet] move by offset failed, errCode=%d, offset=%d", errCode, offset);
181 return errCode;
182 }
183 ++offset;
184 }
185 return errCode;
186 }
187
MoveToNext() const188 int RdSingleVerResultSet::MoveToNext() const
189 {
190 int errCode = PreCheckResultSet();
191 if (errCode != E_OK) {
192 LOGE("[RdSinResSet] PreCheckResultSet failed");
193 return errCode;
194 }
195
196 if (position_ == INIT_POSITION && isMovedBefore_) {
197 ++position_;
198 return E_OK;
199 }
200 errCode = handle_->MoveToNext(resultSet_);
201 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
202 LOGE("[RdSinResSet] move next failed, errCode=%d.", errCode);
203 return errCode;
204 } else if (errCode == -E_NOT_FOUND) {
205 if (!isMovedBefore_) {
206 LOGE("[RdSinResSet] move next failed, result set is empty");
207 return -E_RESULT_SET_EMPTY;
208 }
209 // nothing to do when position_ equal with endposition_ which isn't equal with INIT_POSITION
210 if (endPosition_ == INIT_POSITION || position_ != endPosition_) {
211 ++position_;
212 endPosition_ = position_;
213 }
214 return errCode;
215 } else {
216 // E_OK
217 ++position_;
218 isMovedBefore_ = true;
219 if (position_ == endPosition_ && endPosition_ != INIT_POSITION) {
220 // incase we have chosen an end, but new data put in after that
221 endPosition_ = position_ + 1;
222 }
223 }
224 return errCode;
225 }
226
MoveToPrev() const227 int RdSingleVerResultSet::MoveToPrev() const
228 {
229 int errCode = PreCheckResultSet();
230 if (errCode != E_OK) {
231 LOGE("[RdSinResSet] PreCheckResultSet failed");
232 return errCode;
233 }
234
235 if (position_ == endPosition_ && endPosition_ != INIT_POSITION) {
236 --position_;
237 return E_OK;
238 }
239
240 errCode = handle_->MoveToPrev(resultSet_);
241 if (errCode != E_OK) {
242 if (errCode == -E_NOT_FOUND) {
243 LOGD("[RdSinResSet] move prev reach left end, errCode=%d.", errCode);
244 position_ = INIT_POSITION;
245 return errCode;
246 }
247 LOGE("[RdSinResSet] move prev failed, errCode=%d.", errCode);
248 return errCode;
249 }
250
251 if (position_ <= 0) {
252 position_ = 0;
253 } else {
254 --position_;
255 }
256
257 return errCode;
258 }
259
MoveTo(int position) const260 int RdSingleVerResultSet::MoveTo(int position) const
261 {
262 int errCode = PreCheckResultSet();
263 if (errCode != E_OK) {
264 return errCode;
265 }
266
267 if (position < 0) {
268 LOGW("[RdSinResSet][MoveTo] Target Position=%d invalid.", position);
269 }
270
271 return Move(position - position_);
272 }
273
MoveToFirst()274 int RdSingleVerResultSet::MoveToFirst()
275 {
276 std::lock_guard<std::mutex> lockGuard(mutex_);
277 if (!isMovedBefore_) {
278 return MoveToNext();
279 }
280 if (position_ == INIT_POSITION) {
281 ++position_;
282 return E_OK;
283 }
284
285 int errCode = E_OK;
286 do {
287 errCode = MoveToPrev();
288 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
289 LOGE("[RdSinResSet] move to first failed, errCode=%d, position=%d", errCode, position_);
290 return errCode;
291 }
292 if (errCode == -E_NOT_FOUND) {
293 ++position_;
294 break;
295 }
296 } while (errCode == E_OK);
297
298 return E_OK;
299 }
300
MoveToLast()301 int RdSingleVerResultSet::MoveToLast()
302 {
303 std::lock_guard<std::mutex> lockGuard(mutex_);
304 int errCode = E_OK;
305 do {
306 errCode = MoveToNext();
307 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
308 LOGE("[RdSinResSet] move to last failed, errCode=%d, position=%d", errCode, position_);
309 return errCode;
310 }
311 if (errCode == -E_NOT_FOUND) {
312 --position_;
313 break;
314 }
315 } while (errCode == E_OK);
316
317 return E_OK;
318 }
319
IsFirst() const320 bool RdSingleVerResultSet::IsFirst() const
321 {
322 if (GetCount() == 0) {
323 return false;
324 }
325 if (GetPosition() == 0) {
326 return true;
327 }
328 return false;
329 }
330
IsLast() const331 bool RdSingleVerResultSet::IsLast() const
332 {
333 int count = GetCount();
334 if (count == 0) {
335 return false;
336 }
337 if (GetPosition() == (count - 1)) {
338 return true;
339 }
340 return false;
341 }
342
IsBeforeFirst() const343 bool RdSingleVerResultSet::IsBeforeFirst() const
344 {
345 if (GetCount() == 0) {
346 return true;
347 }
348 if (GetPosition() <= INIT_POSITION) {
349 return true;
350 }
351 return false;
352 }
353
IsAfterLast() const354 bool RdSingleVerResultSet::IsAfterLast() const
355 {
356 int count = GetCount();
357 if (count == 0) {
358 return true;
359 }
360 if (GetPosition() >= count) {
361 return true;
362 }
363 return false;
364 }
365
GetEntry(Entry & entry) const366 int RdSingleVerResultSet::GetEntry(Entry &entry) const
367 {
368 std::lock_guard<std::mutex> lockGuard(mutex_);
369 int errCode = PreCheckResultSet();
370 if (errCode != E_OK) {
371 return errCode;
372 }
373
374 if (position_ == INIT_POSITION || (position_ == endPosition_ && endPosition_ != INIT_POSITION)) {
375 return -E_NO_SUCH_ENTRY;
376 }
377 errCode = handle_->GetEntry(resultSet_, entry);
378 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
379 LOGE("[RdSinResSet][GetEntry] failed to get entry form result set.");
380 }
381 return errCode == -E_NOT_FOUND ? -E_NO_SUCH_ENTRY : errCode;
382 }
383 } // namespace DistributedDB