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