/Users/deen/code/yugabyte-db/src/yb/docdb/consensus_frontier.cc
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 | | #include "yb/docdb/consensus_frontier.h" |
15 | | |
16 | | #include <google/protobuf/any.pb.h> |
17 | | |
18 | | #include "yb/docdb/docdb.pb.h" |
19 | | #include "yb/gutil/casts.h" |
20 | | #include "yb/util/tostring.h" |
21 | | |
22 | | namespace yb { |
23 | | namespace docdb { |
24 | | |
25 | 15.5M | ConsensusFrontier::~ConsensusFrontier() { |
26 | 15.5M | } |
27 | | |
28 | 0 | bool ConsensusFrontier::Equals(const UserFrontier& pre_rhs) const { |
29 | 0 | const ConsensusFrontier& rhs = down_cast<const ConsensusFrontier&>(pre_rhs); |
30 | 0 | return op_id_ == rhs.op_id_ && |
31 | 0 | hybrid_time_ == rhs.hybrid_time_ && |
32 | 0 | history_cutoff_ == rhs.history_cutoff_ && |
33 | 0 | hybrid_time_filter_ == rhs.hybrid_time_filter_ && |
34 | 0 | max_value_level_ttl_expiration_time_ == rhs.max_value_level_ttl_expiration_time_; |
35 | 0 | } |
36 | | |
37 | 281k | void ConsensusFrontier::ToPB(google::protobuf::Any* any) const { |
38 | 281k | ConsensusFrontierPB pb; |
39 | 281k | op_id_.ToPB(pb.mutable_op_id()); |
40 | 281k | pb.set_hybrid_time(hybrid_time_.ToUint64()); |
41 | 281k | pb.set_history_cutoff(history_cutoff_.ToUint64()); |
42 | 281k | if (hybrid_time_filter_.is_valid()) { |
43 | 0 | pb.set_hybrid_time_filter(hybrid_time_filter_.ToUint64()); |
44 | 0 | } |
45 | 281k | pb.set_max_value_level_ttl_expiration_time(max_value_level_ttl_expiration_time_.ToUint64()); |
46 | 281k | any->PackFrom(pb); |
47 | 281k | } |
48 | | |
49 | 18.6k | void ConsensusFrontier::FromPB(const google::protobuf::Any& any) { |
50 | 18.6k | ConsensusFrontierPB pb; |
51 | 18.6k | any.UnpackTo(&pb); |
52 | 18.6k | op_id_ = OpId::FromPB(pb.op_id()); |
53 | 18.6k | hybrid_time_ = HybridTime(pb.hybrid_time()); |
54 | 18.6k | history_cutoff_ = NormalizeHistoryCutoff(HybridTime(pb.history_cutoff())); |
55 | 18.6k | if (pb.has_hybrid_time_filter()) { |
56 | 0 | hybrid_time_filter_ = HybridTime(pb.hybrid_time_filter()); |
57 | 18.6k | } else { |
58 | 18.6k | hybrid_time_filter_ = HybridTime(); |
59 | 18.6k | } |
60 | 18.6k | max_value_level_ttl_expiration_time_ = |
61 | 18.6k | HybridTime::FromPB(pb.max_value_level_ttl_expiration_time()); |
62 | 18.6k | } |
63 | | |
64 | 0 | void ConsensusFrontier::FromOpIdPBDeprecated(const OpIdPB& pb) { |
65 | 0 | op_id_ = OpId::FromPB(pb); |
66 | 0 | } |
67 | | |
68 | 9.11k | std::string ConsensusFrontier::ToString() const { |
69 | 9.11k | return YB_CLASS_TO_STRING( |
70 | 9.11k | op_id, hybrid_time, history_cutoff, hybrid_time_filter, max_value_level_ttl_expiration_time); |
71 | 9.11k | } |
72 | | |
73 | | namespace { |
74 | | |
75 | | // Check if the given updated value is a correct "update" for the given previous value in the |
76 | | // specified direction. If one of the two values is not defined according to the bool conversion, |
77 | | // then there is no error. |
78 | | template<typename T> |
79 | | bool IsUpdateValidForField( |
80 | 8.53k | const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) { |
81 | 8.53k | if (!this_value || !updated_value) { |
82 | | // If any of the two values is undefined, we don't treat this as an error. |
83 | 0 | return true; |
84 | 0 | } |
85 | 8.53k | switch (update_type) { |
86 | 8.53k | case rocksdb::UpdateUserValueType::kLargest: |
87 | 8.53k | return updated_value >= this_value; |
88 | 0 | case rocksdb::UpdateUserValueType::kSmallest: |
89 | 0 | return updated_value <= this_value; |
90 | 0 | } |
91 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); |
92 | 0 | } consensus_frontier.cc:_ZN2yb5docdb12_GLOBAL__N_121IsUpdateValidForFieldINS_4OpIdEEEbRKT_S6_N7rocksdb19UpdateUserValueTypeE Line | Count | Source | 80 | 4.26k | const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) { | 81 | 4.26k | if (!this_value || !updated_value) { | 82 | | // If any of the two values is undefined, we don't treat this as an error. | 83 | 0 | return true; | 84 | 0 | } | 85 | 4.26k | switch (update_type) { | 86 | 4.26k | case rocksdb::UpdateUserValueType::kLargest: | 87 | 4.26k | return updated_value >= this_value; | 88 | 0 | case rocksdb::UpdateUserValueType::kSmallest: | 89 | 0 | return updated_value <= this_value; | 90 | 0 | } | 91 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); | 92 | 0 | } |
consensus_frontier.cc:_ZN2yb5docdb12_GLOBAL__N_121IsUpdateValidForFieldINS_10HybridTimeEEEbRKT_S6_N7rocksdb19UpdateUserValueTypeE Line | Count | Source | 80 | 4.26k | const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) { | 81 | 4.26k | if (!this_value || !updated_value) { | 82 | | // If any of the two values is undefined, we don't treat this as an error. | 83 | 0 | return true; | 84 | 0 | } | 85 | 4.26k | switch (update_type) { | 86 | 4.26k | case rocksdb::UpdateUserValueType::kLargest: | 87 | 4.26k | return updated_value >= this_value; | 88 | 0 | case rocksdb::UpdateUserValueType::kSmallest: | 89 | 0 | return updated_value <= this_value; | 90 | 0 | } | 91 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); | 92 | 0 | } |
|
93 | | |
94 | | template<typename T> |
95 | | void UpdateField( |
96 | 50.7M | T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) { |
97 | 50.7M | switch (update_type) { |
98 | 25.4M | case rocksdb::UpdateUserValueType::kLargest: |
99 | 25.4M | this_value->MakeAtLeast(new_value); |
100 | 25.4M | return; |
101 | 25.3M | case rocksdb::UpdateUserValueType::kSmallest: |
102 | 25.3M | this_value->MakeAtMost(new_value); |
103 | 25.3M | return; |
104 | 0 | } |
105 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); |
106 | 0 | } consensus_frontier.cc:_ZN2yb5docdb12_GLOBAL__N_111UpdateFieldINS_4OpIdEEEvPT_RKS4_N7rocksdb19UpdateUserValueTypeE Line | Count | Source | 96 | 12.6M | T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) { | 97 | 12.6M | switch (update_type) { | 98 | 6.35M | case rocksdb::UpdateUserValueType::kLargest: | 99 | 6.35M | this_value->MakeAtLeast(new_value); | 100 | 6.35M | return; | 101 | 6.34M | case rocksdb::UpdateUserValueType::kSmallest: | 102 | 6.34M | this_value->MakeAtMost(new_value); | 103 | 6.34M | return; | 104 | 0 | } | 105 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); | 106 | 0 | } |
consensus_frontier.cc:_ZN2yb5docdb12_GLOBAL__N_111UpdateFieldINS_10HybridTimeEEEvPT_RKS4_N7rocksdb19UpdateUserValueTypeE Line | Count | Source | 96 | 38.0M | T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) { | 97 | 38.0M | switch (update_type) { | 98 | 19.0M | case rocksdb::UpdateUserValueType::kLargest: | 99 | 19.0M | this_value->MakeAtLeast(new_value); | 100 | 19.0M | return; | 101 | 19.0M | case rocksdb::UpdateUserValueType::kSmallest: | 102 | 19.0M | this_value->MakeAtMost(new_value); | 103 | 19.0M | return; | 104 | 0 | } | 105 | 0 | FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type); | 106 | 0 | } |
|
107 | | |
108 | | } // anonymous namespace |
109 | | |
110 | | void ConsensusFrontier::Update( |
111 | 12.6M | const rocksdb::UserFrontier& pre_rhs, rocksdb::UpdateUserValueType update_type) { |
112 | 12.6M | const ConsensusFrontier& rhs = down_cast<const ConsensusFrontier&>(pre_rhs); |
113 | 12.6M | UpdateField(&op_id_, rhs.op_id_, update_type); |
114 | 12.6M | UpdateField(&hybrid_time_, rhs.hybrid_time_, update_type); |
115 | 12.6M | UpdateField(&history_cutoff_, rhs.history_cutoff_, update_type); |
116 | | // Reset filter after compaction. |
117 | 12.6M | hybrid_time_filter_ = HybridTime(); |
118 | 12.6M | UpdateField(&max_value_level_ttl_expiration_time_, |
119 | 12.6M | rhs.max_value_level_ttl_expiration_time_, update_type); |
120 | 12.6M | } |
121 | | |
122 | 3.45M | Slice ConsensusFrontier::Filter() const { |
123 | 3.45M | return hybrid_time_filter_.is_valid() |
124 | 0 | ? Slice(pointer_cast<const char*>(&hybrid_time_filter_), sizeof(hybrid_time_filter_)) |
125 | 3.45M | : Slice(); |
126 | 3.45M | } |
127 | | |
128 | | bool ConsensusFrontier::IsUpdateValid( |
129 | 4.26k | const rocksdb::UserFrontier& pre_rhs, rocksdb::UpdateUserValueType update_type) const { |
130 | 4.26k | const ConsensusFrontier& rhs = down_cast<const ConsensusFrontier&>(pre_rhs); |
131 | | |
132 | | // We don't check history cutoff here, because it is not an error when the the history cutoff |
133 | | // for a later compaction is lower than that for an earlier compaction. This can happen if |
134 | | // FLAGS_timestamp_history_retention_interval_sec increases. |
135 | 4.26k | return IsUpdateValidForField(op_id_, rhs.op_id_, update_type) && |
136 | 4.26k | IsUpdateValidForField(hybrid_time_, rhs.hybrid_time_, update_type); |
137 | 4.26k | } |
138 | | |
139 | | } // namespace docdb |
140 | | } // namespace yb |