Google Cloud Bigtable C++ Client  1.1.0
A C++ Client Library for Google Cloud Bigtable
row_range.h
Go to the documentation of this file.
1 // Copyright 2017 Google Inc.
2 //
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 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_ROW_RANGE_H_
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_ROW_RANGE_H_
17 
18 #include "google/cloud/bigtable/internal/prefix_range_end.h"
19 #include "google/cloud/bigtable/row_key.h"
20 #include "google/cloud/bigtable/version.h"
21 #include <google/bigtable/v2/data.pb.h>
22 #include <chrono>
23 #include <utility>
24 
25 namespace google {
26 namespace cloud {
27 namespace bigtable {
28 inline namespace BIGTABLE_CLIENT_NS {
29 /**
30  * Define the interfaces to create row key ranges.
31  *
32  * Example:
33  * @code
34  * // Create a range for the keys starting with the given prefix.
35  * auto range = bigtable::RowRange("foo/");
36  * @endcode
37  */
38 class RowRange {
39  public:
40  explicit RowRange(::google::bigtable::v2::RowRange rhs)
41  : row_range_(std::move(rhs)) {}
42 
43  RowRange(RowRange&&) noexcept = default;
44  RowRange& operator=(RowRange&&) noexcept = default;
45  RowRange(RowRange const&) = default;
46  RowRange& operator=(RowRange const&) = default;
47 
48  /// Return the infinite range, i.e., a range including all possible keys.
49  static RowRange InfiniteRange() { return RowRange(); }
50 
51  /// Return the range starting at @p begin (included), with no upper limit.
52  template <typename T>
53  static RowRange StartingAt(T&& begin) {
54  RowRange result;
55  result.row_range_.set_start_key_closed(std::forward<T>(begin));
56  return result;
57  }
58 
59  /// Return the range ending at @p end (included), with no lower limit.
60  template <typename T>
61  static RowRange EndingAt(T&& end) {
62  RowRange result;
63  result.row_range_.set_end_key_closed(std::forward<T>(end));
64  return result;
65  }
66 
67  /// Return an empty range.
68  static RowRange Empty() {
69  RowRange result;
70  // Return an open interval that contains no key, using "\0" for the end key.
71  // We can't use "", because when appearing as the end it means 'infinity'.
72  result.row_range_.set_start_key_open("");
73  result.row_range_.set_end_key_open(std::string("\0", 1));
74  return result;
75  }
76 
77  /// Return the range representing the interval [@p begin, @p end).
78  template <typename T, typename U>
79  static RowRange Range(T&& begin, U&& end) {
80  return RightOpen(std::forward<T>(begin), std::forward<U>(end));
81  }
82 
83  /// Return a range that contains all the keys starting with @p prefix.
84  template <typename T>
85  static RowRange Prefix(T&& prefix) {
86  auto end = internal::PrefixRangeEnd(prefix);
87  return RightOpen(std::forward<T>(prefix), std::move(end));
88  }
89 
90  //@{
91  /// @name Less common, yet sometimes useful, ranges.
92  /// Return a range representing the interval [@p begin, @p end).
93  template <typename T, typename U>
94  static RowRange RightOpen(T&& begin, U&& end) {
95  RowRange result;
96  result.row_range_.set_start_key_closed(std::forward<T>(begin));
97  if (!internal::IsEmptyRowKey(end)) {
98  result.row_range_.set_end_key_open(std::forward<U>(end));
99  }
100  return result;
101  }
102 
103  /// Return a range representing the interval (@p begin, @p end].
104  template <typename T, typename U>
105  static RowRange LeftOpen(T&& begin, U&& end) {
106  RowRange result;
107  result.row_range_.set_start_key_open(std::forward<T>(begin));
108  if (!internal::IsEmptyRowKey(end)) {
109  result.row_range_.set_end_key_closed(std::forward<U>(end));
110  }
111  return result;
112  }
113 
114  /// Return a range representing the interval (@p begin, @p end).
115  template <typename T, typename U>
116  static RowRange Open(T&& begin, U&& end) {
117  RowRange result;
118  result.row_range_.set_start_key_open(std::forward<T>(begin));
119  if (!internal::IsEmptyRowKey(end)) {
120  result.row_range_.set_end_key_open(std::forward<U>(end));
121  }
122  return result;
123  }
124 
125  /// Return a range representing the interval [@p begin, @p end].
126  template <typename T, typename U>
127  static RowRange Closed(T&& begin, U&& end) {
128  RowRange result;
129  result.row_range_.set_start_key_closed(std::forward<T>(begin));
130  if (!internal::IsEmptyRowKey(end)) {
131  result.row_range_.set_end_key_closed(std::forward<U>(end));
132  }
133  return result;
134  }
135  //@}
136 
137  /**
138  * Return true if the range is empty.
139  *
140  * Note that some ranges (such as `["", ""]`) are not empty but only include
141  * invalid row keys.
142  */
143  bool IsEmpty() const;
144 
145  /// Return true if @p key is in the range.
146  template <typename T>
147  bool Contains(T const& key) const {
148  return !BelowStart(key) && !AboveEnd(key);
149  }
150 
151  /**
152  * Compute the intersection against another RowRange.
153  *
154  * @return a 2-tuple, the first element is a boolean, with value `true` if
155  * there is some intersection, the second element is the intersection.
156  * If there is no intersection the first element is `false` and the second
157  * element has a valid, but unspecified value.
158  */
159  std::pair<bool, RowRange> Intersect(RowRange const& range) const;
160 
161  /// Return the filter expression as a protobuf.
162  ::google::bigtable::v2::RowRange const& as_proto() const& {
163  return row_range_;
164  }
165 
166  /// Move out the underlying protobuf value.
167  ::google::bigtable::v2::RowRange&& as_proto() && {
168  return std::move(row_range_);
169  }
170 
171  private:
172  /// Private to avoid mistaken creation of uninitialized ranges.
173  RowRange() = default;
174 
175  /// Return true if @p key is below the start.
176  bool BelowStart(RowKeyType const& key) const;
177 
178  /// Return true if @p key is above the end.
179  bool AboveEnd(RowKeyType const& key) const;
180 
181  /// Overloads for types != RowKeyType.
182  template <typename T>
183  bool BelowStart(T const& key) const {
184  return BelowStart(RowKeyType(key));
185  }
186 
187  /// Overloads for types != RowKeyType.
188  template <typename T>
189  bool AboveEnd(T const& key) const {
190  return AboveEnd(RowKeyType(key));
191  }
192 
193  private:
194  ::google::bigtable::v2::RowRange row_range_;
195 };
196 
197 bool operator==(RowRange const& lhs, RowRange const& rhs);
198 
199 inline bool operator!=(RowRange const& lhs, RowRange const& rhs) {
200  return std::rel_ops::operator!=(lhs, rhs);
201 }
202 
203 /// Print a human-readable representation of the range, mostly for testing.
204 std::ostream& operator<<(std::ostream& os, RowRange const& x);
205 } // namespace BIGTABLE_CLIENT_NS
206 } // namespace bigtable
207 } // namespace cloud
208 } // namespace google
209 
210 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_BIGTABLE_ROW_RANGE_H_
#define BIGTABLE_CLIENT_NS
Definition: version.h:22