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_db_api.h"
18 #include "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 offset = offset > INT_MAX ? INT_MAX : offset;
161 offset = offset < INT_MIN ? INT_MIN : offset;
162
163 while (offset > 0) {
164 errCode = MoveToNext();
165 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
166 LOGE("[RdSinResSet] move by offset failed, errCode=%d, offset=%d", errCode, offset);
167 return errCode;
168 }
169 --offset;
170 if (errCode == -E_NOT_FOUND && offset >= 0) {
171 LOGE("[RdSingleVerStorageExecutor] move offset: %d, out of bounds or result set empty, position: %d",
172 offset, position_);
173 return -E_INVALID_ARGS;
174 }
175 }
176 while (offset < 0) {
177 errCode = MoveToPrev();
178 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
179 LOGE("[RdSinResSet] move by offset failed, errCode=%d, offset=%d", errCode, offset);
180 return errCode;
181 }
182 ++offset;
183 if (errCode == -E_NOT_FOUND && offset <= 0) {
184 LOGE("[RdSingleVerStorageExecutor] move offset: %d, out of bounds or result set empty, position: %d",
185 offset, position_);
186 return -E_INVALID_ARGS;
187 }
188 }
189 return errCode;
190 }
191
MoveToNext() const192 int RdSingleVerResultSet::MoveToNext() const
193 {
194 int errCode = PreCheckResultSet();
195 if (errCode != E_OK) {
196 LOGE("[RdSinResSet] PreCheckResultSet failed");
197 return errCode;
198 }
199
200 if (position_ == INIT_POSITION && isMovedBefore_) {
201 ++position_;
202 return E_OK;
203 }
204 errCode = handle_->MoveToNext(resultSet_);
205 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
206 LOGE("[RdSinResSet] move next failed, errCode=%d.", errCode);
207 return errCode;
208 } else if (errCode == -E_NOT_FOUND) {
209 if (!isMovedBefore_) {
210 LOGE("[RdSinResSet] move next failed, result set is empty");
211 return -E_RESULT_SET_EMPTY;
212 }
213 // nothing to do when position_ equal with endposition_ which isn't equal with INIT_POSITION
214 if (endPosition_ == INIT_POSITION || position_ != endPosition_) {
215 ++position_;
216 endPosition_ = position_;
217 }
218 return errCode;
219 } else {
220 // E_OK
221 ++position_;
222 isMovedBefore_ = true;
223 if (position_ == endPosition_ && endPosition_ != INIT_POSITION) {
224 // incase we have chosen an end, but new data put in after that
225 endPosition_ = position_ + 1;
226 }
227 }
228 return errCode;
229 }
230
MoveToPrev() const231 int RdSingleVerResultSet::MoveToPrev() const
232 {
233 int errCode = PreCheckResultSet();
234 if (errCode != E_OK) {
235 LOGE("[RdSinResSet] PreCheckResultSet failed");
236 return errCode;
237 }
238
239 if (position_ == endPosition_ && endPosition_ != INIT_POSITION) {
240 --position_;
241 return E_OK;
242 }
243
244 errCode = handle_->MoveToPrev(resultSet_);
245 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
246 LOGE("[RdSinResSet] move prev failed, errCode=%d.", errCode);
247 return errCode;
248 }
249
250 if (errCode == -E_NOT_FOUND) {
251 position_ = INIT_POSITION;
252 } else {
253 if (position_ <= 0) {
254 position_ = 0;
255 } else {
256 --position_;
257 }
258 }
259 return errCode;
260 }
261
MoveTo(int position) const262 int RdSingleVerResultSet::MoveTo(int position) const
263 {
264 int errCode = PreCheckResultSet();
265 if (errCode != E_OK) {
266 return errCode;
267 }
268
269 if (position < 0) {
270 LOGW("[RdSinResSet][MoveTo] Target Position=%d invalid.", position);
271 }
272
273 return Move(position - position_);
274 }
275
MoveToFirst()276 int RdSingleVerResultSet::MoveToFirst()
277 {
278 if (!isMovedBefore_) {
279 return MoveToNext();
280 }
281 if (position_ == INIT_POSITION) {
282 ++position_;
283 return E_OK;
284 }
285
286 int errCode = E_OK;
287 do {
288 errCode = MoveToPrev();
289 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
290 LOGE("[RdSinResSet] move to first failed, errCode=%d, position=%d", errCode, position_);
291 return errCode;
292 }
293 if (errCode == -E_NOT_FOUND) {
294 ++position_;
295 break;
296 }
297 } while (errCode == E_OK);
298
299 return E_OK;
300 }
301
MoveToLast()302 int RdSingleVerResultSet::MoveToLast()
303 {
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 int position = GetPosition();
323 if (GetCount() == 0) {
324 return false;
325 }
326 if (position == 0) {
327 return true;
328 }
329 return false;
330 }
331
IsLast() const332 bool RdSingleVerResultSet::IsLast() const
333 {
334 int position = GetPosition();
335 int count = GetCount();
336 if (count == 0) {
337 return false;
338 }
339 if (position == (count - 1)) {
340 return true;
341 }
342 return false;
343 }
344
IsBeforeFirst() const345 bool RdSingleVerResultSet::IsBeforeFirst() const
346 {
347 int position = GetPosition();
348
349 if (GetCount() == 0) {
350 return true;
351 }
352 if (position <= INIT_POSITION) {
353 return true;
354 }
355 return false;
356 }
357
IsAfterLast() const358 bool RdSingleVerResultSet::IsAfterLast() const
359 {
360 int position = GetPosition();
361 int count = GetCount();
362 if (count == 0) {
363 return true;
364 }
365 if (position >= count) {
366 return true;
367 }
368 return false;
369 }
370
GetEntry(Entry & entry) const371 int RdSingleVerResultSet::GetEntry(Entry &entry) const
372 {
373 std::lock_guard<std::mutex> lockGuard(mutex_);
374 int errCode = PreCheckResultSet();
375 if (errCode != E_OK) {
376 return errCode;
377 }
378
379 if (position_ == INIT_POSITION || (position_ == endPosition_ && endPosition_ != INIT_POSITION)) {
380 return -E_NO_SUCH_ENTRY;
381 }
382 errCode = handle_->GetEntry(resultSet_, entry);
383 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
384 LOGE("[RdSinResSet][GetEntry] failed to get entry form result set.");
385 }
386 return errCode == -E_NOT_FOUND ? -E_NO_SUCH_ENTRY : errCode;
387 }
388 } // namespace DistributedDB