Kinetic C/C++ Client
 All Classes Functions Variables Pages
key_range_iterator.cc
1 /*
2  * kinetic-cpp-client
3  * Copyright (C) 2014 Seagate Technology.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  */
20 
21 #include "kinetic/key_range_iterator.h"
22 #include <stdexcept>
23 
24 namespace kinetic {
25 
26 using std::string;
27 using std::vector;
28 
29 KeyRangeIterator KeyRangeEnd() {
30  KeyRangeIterator it;
31  return it;
32 }
33 
34 KeyRangeIterator::KeyRangeIterator()
35  : bconn_(NULL),
36  first_(""),
37  first_inc_(false),
38  last_(""),
39  last_inc_(false),
40  framesz_(1),
41  reverse_order_(false),
42  relpos_(-1),
43  eol_(true),
44  keys_() { }
45 
46 KeyRangeIterator::KeyRangeIterator(
47  BlockingKineticConnection* p,
48  unsigned int framesz,
49  string start,
50  bool start_inclusive,
51  string end,
52  bool end_inclusive)
53  : bconn_(p),
54  first_(start),
55  first_inc_(start_inclusive),
56  last_(end),
57  last_inc_(end_inclusive),
58  framesz_(framesz),
59  reverse_order_(false),
60  relpos_(-1),
61  eol_(false),
62  keys_() {
63  this->next_frame();
64 }
65 
66 KeyRangeIterator::KeyRangeIterator(const KeyRangeIterator& rhs)
67  : bconn_(rhs.bconn_),
68  first_(rhs.first_),
69  first_inc_(rhs.first_inc_),
70  last_(rhs.last_),
71  last_inc_(rhs.last_inc_),
72  framesz_(rhs.framesz_),
73  reverse_order_(rhs.reverse_order_),
74  relpos_(rhs.relpos_),
75  eol_(rhs.eol_),
76  keys_() {
77  if (rhs.keys_.get() != NULL) {
78  this->keys_ = unique_ptr<vector<string>>(new vector<string>(*rhs.keys_));
79  }
80 }
81 
82 
83 KeyRangeIterator& KeyRangeIterator::operator=(KeyRangeIterator const& rhs) {
84  if (&rhs != this) {
85  this->bconn_ = rhs.bconn_;
86  this->first_ = rhs.first_;
87  this->first_inc_ = rhs.first_inc_;
88  this->last_ = rhs.last_;
89  this->last_inc_ = rhs.last_inc_;
90  this->framesz_ = rhs.framesz_;
91  this->reverse_order_ = rhs.reverse_order_;
92  this->relpos_ = rhs.relpos_;
93  this->eol_ = rhs.eol_;
94  this->keys_.reset();
95  if (rhs.keys_.get() != NULL) {
96  this->keys_ = unique_ptr<vector<string>>(new vector<string>(*rhs.keys_));
97  }
98  }
99  return *this;
100 }
101 
102 KeyRangeIterator::~KeyRangeIterator() {}
103 
104 bool KeyRangeIterator::operator==(KeyRangeIterator const& rhs) const {
105  return ((rhs.eol_ == true && this->eol_ == true)
106  || (rhs.relpos_ != -1 && this->relpos_ != -1
107  && rhs.keys_.get() != NULL && this->keys_.get() != NULL
108  && (*rhs.keys_)[rhs.relpos_] == (*this->keys_)[this->relpos_]));
109 }
110 
111 bool KeyRangeIterator::operator!=(
112  KeyRangeIterator const& rhs) const {
113  return !(*this == rhs);
114 }
115 
116 KeyRangeIterator& KeyRangeIterator::operator++() {
117  if (this->relpos_ == -1 || this->keys_.get() == NULL) {
118  throw std::runtime_error("Iterator is in a bad state");
119  }
120 
121  this->advance();
122 
123  return *this;
124 }
125 
126 KeyRangeIterator KeyRangeIterator::operator++(int unused) {
127  if (this->relpos_ == -1 || this->keys_.get() == NULL) {
128  throw std::runtime_error("Iterator is in a bad state");
129  }
130 
131  KeyRangeIterator copy(*this);
132 
133  this->advance();
134 
135  return copy;
136 }
137 
138 std::string* KeyRangeIterator::operator->() {
139  if (this->relpos_ == -1 || this->keys_.get() == NULL) {
140  throw std::runtime_error("Iterator is in a bad state");
141  }
142  if (this->eol_) {
143  throw std::out_of_range("Iterator is out of bounds.");
144  }
145  return &(*this->keys_)[this->relpos_];
146 }
147 
148 const std::string& KeyRangeIterator::operator*() const {
149  if (this->relpos_ == -1 || this->keys_.get() == NULL) {
150  throw std::runtime_error("Iterator is in a bad state");
151  }
152  if (this->eol_) {
153  throw std::out_of_range("Iterator is out of bounds.");
154  }
155  return (*this->keys_)[this->relpos_];
156 }
157 
158 void KeyRangeIterator::next_frame() {
159  // Update the moving boundary key if it's not the first ever load
160  if (this->relpos_ != -1 && this->keys_.get() != NULL) {
161  this->first_ = (*this->keys_)[this->keys_->size() - 1];
162  this->first_inc_ = false;
163  }
164 
165  kinetic::KineticStatus status = this->bconn_->GetKeyRange(
166  this->first_, this->first_inc_,
167  this->last_, this->last_inc_,
168  this->reverse_order_, this->framesz_,
169  this->keys_);
170  if (!status.ok()) {
171  this->relpos_ = -1; // ERROR
172  throw std::runtime_error(status.message());
173  }
174 
175  this->relpos_ = 0;
176  if (this->keys_.get() == NULL || this->keys_->size() == 0) {
177  this->eol_ = true;
178  }
179 }
180 
181 void KeyRangeIterator::advance() {
182  this->relpos_++;
183  if (this->relpos_ == -1
184  || this->relpos_ == static_cast<int>(this->keys_->size())) {
185  this->next_frame();
186  }
187 }
188 
189 } // namespace kinetic
Indicates whether a Kinetic operation (get, put, security, etc) put succeeded or failed. Unlike Status it provides details like whether the failure resulted from a version or an HMAC error.