YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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
11.1k
  SliceKeyBound() {}
42
  SliceKeyBound(const Slice& key, BoundType type)
43
10.8k
      : key_(key), type_(type) {}
44
45
1.89M
  bool CanInclude(const Slice& other) const {
46
1.89M
    if (!is_valid()) {
47
951
      return true;
48
951
    }
49
1.89M
    int comp = key_.compare(Slice(other.data(), std::min(other.size(), key_.size())));
50
1.89M
    if (is_lower()) {
51
950k
      comp = -comp;
52
950k
    }
53
1.68M
    return is_exclusive() ? comp > 0 : comp >= 0;
54
1.89M
  }
55
56
  static const SliceKeyBound& Invalid();
57
58
1.89M
  bool is_valid() const { return type_ != BoundType::kInvalid; }
59
5.42k
  const Slice& key() const { return key_; }
60
61
1.90M
  bool is_exclusive() const {
62
1.90M
    return type_ == BoundType::kExclusiveLower || type_ == BoundType::kExclusiveUpper;
63
1.90M
  }
64
65
1.89M
  bool is_lower() const {
66
1.89M
    return type_ == BoundType::kExclusiveLower || type_ == BoundType::kInclusiveLower;
67
1.89M
  }
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
259
      is_lower_bound_(false) {}
85
86
  IndexBound(int64 index, bool is_lower_bound) :
87
      index_(index),
88
21
      is_lower_bound_(is_lower_bound) {}
89
90
3.85M
  bool CanInclude(int64 curr_index) const {
91
3.85M
    if (index_ == -1 ) {
92
3.85M
      return true;
93
3.85M
    }
94
258
    return is_lower_bound_ ? index_ <= curr_index : index_ >= curr_index;
95
258
  }
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 = Value::kMaxTtl)
111
      : subdocument_key(subdoc_key),
112
        result(result_),
113
        doc_found(doc_found_),
114
1.16M
        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
945k
      const Slice& subdoc_key, SubDocument* result_, bool* doc_found_ = nullptr) const {
143
945k
    GetRedisSubDocumentData result(subdoc_key, result_, doc_found_);
144
945k
    result.deadline_info = deadline_info;
145
945k
    result.exp = exp;
146
945k
    result.return_type_only = return_type_only;
147
945k
    result.low_subkey = low_subkey;
148
945k
    result.high_subkey = high_subkey;
149
945k
    result.low_index = low_index;
150
945k
    result.high_index = high_index;
151
945k
    result.limit = limit;
152
945k
    return result;
153
945k
  }
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_