/Users/deen/code/yugabyte-db/src/yb/docdb/doc_reader_redis.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_DOCDB_DOC_READER_REDIS_H_ |
15 | | #define YB_DOCDB_DOC_READER_REDIS_H_ |
16 | | |
17 | | #include <string> |
18 | | #include <vector> |
19 | | |
20 | | #include "yb/common/doc_hybrid_time.h" |
21 | | #include "yb/common/read_hybrid_time.h" |
22 | | |
23 | | #include "yb/docdb/docdb_fwd.h" |
24 | | #include "yb/docdb/docdb_types.h" |
25 | | #include "yb/docdb/expiration.h" |
26 | | #include "yb/docdb/value.h" |
27 | | |
28 | | #include "yb/rocksdb/cache.h" |
29 | | |
30 | | #include "yb/util/status_fwd.h" |
31 | | #include "yb/util/strongly_typed_bool.h" |
32 | | |
33 | | namespace yb { |
34 | | namespace docdb { |
35 | | |
36 | | // Indicates if we can get away by only seeking forward, or if we must do a regular seek. |
37 | | YB_STRONGLY_TYPED_BOOL(SeekFwdSuffices); |
38 | | |
39 | | class SliceKeyBound { |
40 | | public: |
41 | 22.4k | SliceKeyBound() {} |
42 | | SliceKeyBound(const Slice& key, BoundType type) |
43 | 21.7k | : key_(key), type_(type) {} |
44 | | |
45 | 3.69M | bool CanInclude(const Slice& other) const { |
46 | 3.69M | if (!is_valid()) { |
47 | 2.63k | return true; |
48 | 2.63k | } |
49 | 3.69M | int comp = key_.compare(Slice(other.data(), std::min(other.size(), key_.size()))); |
50 | 3.69M | if (is_lower()) { |
51 | 1.85M | comp = -comp; |
52 | 1.85M | } |
53 | 3.69M | return is_exclusive() ? comp > 0393k : comp >= 03.29M ; |
54 | 3.69M | } |
55 | | |
56 | | static const SliceKeyBound& Invalid(); |
57 | | |
58 | 3.69M | bool is_valid() const { return type_ != BoundType::kInvalid; } |
59 | 10.8k | const Slice& key() const { return key_; } |
60 | | |
61 | 3.70M | bool is_exclusive() const { |
62 | 3.70M | return type_ == BoundType::kExclusiveLower || type_ == BoundType::kExclusiveUpper3.50M ; |
63 | 3.70M | } |
64 | | |
65 | 3.69M | bool is_lower() const { |
66 | 3.69M | return type_ == BoundType::kExclusiveLower || type_ == BoundType::kInclusiveLower3.49M ; |
67 | 3.69M | } |
68 | | |
69 | 0 | explicit operator bool() const { |
70 | 0 | return is_valid(); |
71 | 0 | } |
72 | | |
73 | | std::string ToString() const; |
74 | | |
75 | | private: |
76 | | Slice key_; |
77 | | BoundType type_ = BoundType::kInvalid; |
78 | | }; |
79 | | |
80 | | class IndexBound { |
81 | | public: |
82 | | IndexBound() : |
83 | | index_(-1), |
84 | 703 | is_lower_bound_(false) {} |
85 | | |
86 | | IndexBound(int64 index, bool is_lower_bound) : |
87 | | index_(index), |
88 | 98 | is_lower_bound_(is_lower_bound) {} |
89 | | |
90 | 7.89M | bool CanInclude(int64 curr_index) const { |
91 | 7.89M | if (index_ == -1 ) { |
92 | 7.89M | return true; |
93 | 7.89M | } |
94 | 941 | return is_lower_bound_ ? index_ <= curr_index516 : index_ >= curr_index425 ; |
95 | 7.89M | } |
96 | | |
97 | | static const IndexBound& Empty(); |
98 | | |
99 | | private: |
100 | | int64 index_; |
101 | | bool is_lower_bound_; |
102 | | }; |
103 | | |
104 | | // Pass data to GetRedisSubDocument function. |
105 | | struct GetRedisSubDocumentData { |
106 | | GetRedisSubDocumentData( |
107 | | const Slice& subdoc_key, |
108 | | SubDocument* result_, |
109 | | bool* doc_found_ = nullptr, |
110 | | MonoDelta default_ttl = ValueControlFields::kMaxTtl) |
111 | | : subdocument_key(subdoc_key), |
112 | | result(result_), |
113 | | doc_found(doc_found_), |
114 | 2.46M | exp(default_ttl) {} |
115 | | |
116 | | Slice subdocument_key; |
117 | | SubDocument* result; |
118 | | bool* doc_found; |
119 | | |
120 | | DeadlineInfo* deadline_info = nullptr; |
121 | | |
122 | | // The TTL and hybrid time are return values external to the SubDocument |
123 | | // which occasionally need to be accessed for TTL calculation. |
124 | | mutable Expiration exp; |
125 | | bool return_type_only = false; |
126 | | |
127 | | // Represent bounds on the first and last subkey to be considered. |
128 | | const SliceKeyBound* low_subkey = &SliceKeyBound::Invalid(); |
129 | | const SliceKeyBound* high_subkey = &SliceKeyBound::Invalid(); |
130 | | |
131 | | // Represent bounds on the first and last ranks to be considered. |
132 | | const IndexBound* low_index = &IndexBound::Empty(); |
133 | | const IndexBound* high_index = &IndexBound::Empty(); |
134 | | // Maximum number of children to add for this subdocument (0 means no limit). |
135 | | size_t limit = 0; |
136 | | // Only store a count of the number of records found, but don't store the records themselves. |
137 | | bool count_only = false; |
138 | | // Stores the count of records found, if count_only option is set. |
139 | | mutable size_t record_count = 0; |
140 | | |
141 | | GetRedisSubDocumentData Adjusted( |
142 | 1.84M | const Slice& subdoc_key, SubDocument* result_, bool* doc_found_ = nullptr) const { |
143 | 1.84M | GetRedisSubDocumentData result(subdoc_key, result_, doc_found_); |
144 | 1.84M | result.deadline_info = deadline_info; |
145 | 1.84M | result.exp = exp; |
146 | 1.84M | result.return_type_only = return_type_only; |
147 | 1.84M | result.low_subkey = low_subkey; |
148 | 1.84M | result.high_subkey = high_subkey; |
149 | 1.84M | result.low_index = low_index; |
150 | 1.84M | result.high_index = high_index; |
151 | 1.84M | result.limit = limit; |
152 | 1.84M | return result; |
153 | 1.84M | } |
154 | | |
155 | | std::string ToString() const; |
156 | | }; |
157 | | |
158 | 0 | inline std::ostream& operator<<(std::ostream& out, const GetRedisSubDocumentData& data) { |
159 | 0 | return out << data.ToString(); |
160 | 0 | } |
161 | | |
162 | | // Returns the whole SubDocument below some node identified by subdocument_key. |
163 | | // subdocument_key should not have a timestamp. |
164 | | // Before the function is called, if seek_fwd_suffices is true, the iterator is expected to be |
165 | | // positioned on or before the first key when called. |
166 | | // After this, the iter should be positioned just outside the considered data range. If low_subkey, |
167 | | // and high_subkey are specified, the iterator will be positioned just past high_subkey. Otherwise, |
168 | | // the iterator will be positioned just past the SubDocument. |
169 | | // This function works with or without object init markers present. |
170 | | // If tombstone and other values are inserted at the same timestamp, it results in undefined |
171 | | // behavior. |
172 | | // The projection, if set, restricts the scan to a subset of keys in the first level. |
173 | | // The projection is used for QL selects to get only a subset of columns. |
174 | | yb::Status GetRedisSubDocument( |
175 | | IntentAwareIterator *db_iter, |
176 | | const GetRedisSubDocumentData& data, |
177 | | const std::vector<PrimitiveValue>* projection = nullptr, |
178 | | SeekFwdSuffices seek_fwd_suffices = SeekFwdSuffices::kTrue); |
179 | | |
180 | | // This version of GetRedisSubDocument creates a new iterator every time. This is not recommended |
181 | | // for multiple calls to subdocs that are sequential or near each other, in e.g. |
182 | | // doc_rowwise_iterator. |
183 | | yb::Status GetRedisSubDocument( |
184 | | const DocDB& doc_db, |
185 | | const GetRedisSubDocumentData& data, |
186 | | const rocksdb::QueryId query_id, |
187 | | const TransactionOperationContext& txn_op_context, |
188 | | CoarseTimePoint deadline, |
189 | | const ReadHybridTime& read_time = ReadHybridTime::Max()); |
190 | | |
191 | | } // namespace docdb |
192 | | } // namespace yb |
193 | | |
194 | | #endif // YB_DOCDB_DOC_READER_REDIS_H_ |