/Users/deen/code/yugabyte-db/src/yb/docdb/consensus_frontier.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_CONSENSUS_FRONTIER_H |
15 | | #define YB_DOCDB_CONSENSUS_FRONTIER_H |
16 | | |
17 | | #include "yb/rocksdb/metadata.h" |
18 | | |
19 | | namespace yb { |
20 | | namespace docdb { |
21 | | |
22 | 37.2k | inline HybridTime NormalizeHistoryCutoff(HybridTime history_cutoff) { |
23 | 37.2k | if (history_cutoff == HybridTime::kMin) { |
24 | 286 | return HybridTime::kInvalid; |
25 | 286 | } |
26 | 36.9k | return history_cutoff; |
27 | 37.2k | } |
28 | | |
29 | | // DocDB implementation of RocksDB UserFrontier. Contains an op id and a hybrid time. The difference |
30 | | // between this and user boundary values is that here hybrid time is taken from committed Raft log |
31 | | // entries, whereas user boundary values extract hybrid time from keys in a memtable. This is |
32 | | // important for transactions, because boundary values would have the commit time of a transaction, |
33 | | // but e.g. "apply intent" Raft log entries will have a later hybrid time, which would be reflected |
34 | | // here. |
35 | | class ConsensusFrontier : public rocksdb::UserFrontier { |
36 | | public: |
37 | 9.99M | std::unique_ptr<UserFrontier> Clone() const override { |
38 | 9.99M | return std::make_unique<ConsensusFrontier>(*this); |
39 | 9.99M | } |
40 | 25.3M | ConsensusFrontier() {} |
41 | | ConsensusFrontier(const OpId& op_id, HybridTime ht, HybridTime history_cutoff) |
42 | | : op_id_(op_id), hybrid_time_(ht), history_cutoff_(NormalizeHistoryCutoff(history_cutoff)) {} |
43 | | |
44 | | virtual ~ConsensusFrontier(); |
45 | | |
46 | | bool Equals(const UserFrontier& rhs) const override; |
47 | | std::string ToString() const override; |
48 | | void ToPB(google::protobuf::Any* pb) const override; |
49 | | void Update(const rocksdb::UserFrontier& rhs, rocksdb::UpdateUserValueType type) override; |
50 | | bool IsUpdateValid(const rocksdb::UserFrontier& rhs, rocksdb::UpdateUserValueType type) const |
51 | | override; |
52 | | void FromPB(const google::protobuf::Any& pb) override; |
53 | | void FromOpIdPBDeprecated(const OpIdPB& pb) override; |
54 | | Slice Filter() const override; |
55 | | |
56 | 5.86M | const OpId& op_id() const { return op_id_; } |
57 | 23.8M | void set_op_id(const OpId& value) { op_id_ = value; } |
58 | | |
59 | | template <class PB> |
60 | 0 | void set_op_id(const PB& pb) { op_id_ = OpId::FromPB(pb); } |
61 | | |
62 | 362k | HybridTime hybrid_time() const { return hybrid_time_; } |
63 | 23.7M | void set_hybrid_time(HybridTime ht) { hybrid_time_ = ht; } |
64 | | |
65 | 13.6k | HybridTime history_cutoff() const { return history_cutoff_; } |
66 | 2.86k | void set_history_cutoff(HybridTime history_cutoff) { |
67 | 2.86k | history_cutoff_ = NormalizeHistoryCutoff(history_cutoff); |
68 | 2.86k | } |
69 | | |
70 | 14 | HybridTime hybrid_time_filter() const { return hybrid_time_filter_; } |
71 | 14 | void set_hybrid_time_filter(HybridTime value) { |
72 | 14 | hybrid_time_filter_ = value; |
73 | 14 | } |
74 | | |
75 | | HybridTime max_value_level_ttl_expiration_time() const |
76 | 84 | { return max_value_level_ttl_expiration_time_; } |
77 | | void set_max_value_level_ttl_expiration_time(HybridTime ht) |
78 | 8.83M | { max_value_level_ttl_expiration_time_ = ht; } |
79 | | |
80 | | private: |
81 | | OpId op_id_; |
82 | | HybridTime hybrid_time_; |
83 | | |
84 | | // We use this to keep track of the maximum history cutoff hybrid time used in any compaction, and |
85 | | // refuse to perform reads at a hybrid time at which we don't have a valid snapshot anymore. Only |
86 | | // the largest frontier of this parameter is being used. |
87 | | HybridTime history_cutoff_; |
88 | | |
89 | | HybridTime hybrid_time_filter_; |
90 | | |
91 | | // Used to track the boundary expiration timestamp for any doc in the file. Tracks value-level |
92 | | // TTL expiration (generated at write-time), table-level TTL is calculated at read-time based |
93 | | // on hybrid_time_. Only the largest frontier of this parameter is being used. |
94 | | HybridTime max_value_level_ttl_expiration_time_; |
95 | | }; |
96 | | |
97 | | typedef rocksdb::UserFrontiersBase<ConsensusFrontier> ConsensusFrontiers; |
98 | | |
99 | 11.8M | inline void set_op_id(const OpId& op_id, ConsensusFrontiers* frontiers) { |
100 | 11.8M | frontiers->Smallest().set_op_id(op_id); |
101 | 11.8M | frontiers->Largest().set_op_id(op_id); |
102 | 11.8M | } |
103 | | |
104 | 11.8M | inline void set_hybrid_time(HybridTime hybrid_time, ConsensusFrontiers* frontiers) { |
105 | 11.8M | frontiers->Smallest().set_hybrid_time(hybrid_time); |
106 | 11.8M | frontiers->Largest().set_hybrid_time(hybrid_time); |
107 | 11.8M | } |
108 | | |
109 | 0 | inline void set_history_cutoff(HybridTime history_cutoff, ConsensusFrontiers* frontiers) { |
110 | 0 | frontiers->Smallest().set_history_cutoff(history_cutoff); |
111 | 0 | frontiers->Largest().set_history_cutoff(history_cutoff); |
112 | 0 | } |
113 | | } // namespace docdb |
114 | | } // namespace yb |
115 | | |
116 | | #endif // YB_DOCDB_CONSENSUS_FRONTIER_H |