YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
35.4M
ConsensusFrontier::~ConsensusFrontier() {
26
35.4M
}
27
28
21
bool ConsensusFrontier::Equals(const UserFrontier& pre_rhs) const {
29
21
  const ConsensusFrontier& rhs = down_cast<const ConsensusFrontier&>(pre_rhs);
30
21
  return op_id_ == rhs.op_id_ &&
31
21
         
hybrid_time_ == rhs.hybrid_time_17
&&
32
21
         
history_cutoff_ == rhs.history_cutoff_13
&&
33
21
         
hybrid_time_filter_ == rhs.hybrid_time_filter_11
&&
34
21
         
max_value_level_ttl_expiration_time_ == rhs.max_value_level_ttl_expiration_time_11
;
35
21
}
36
37
336k
void ConsensusFrontier::ToPB(google::protobuf::Any* any) const {
38
336k
  ConsensusFrontierPB pb;
39
336k
  op_id_.ToPB(pb.mutable_op_id());
40
336k
  pb.set_hybrid_time(hybrid_time_.ToUint64());
41
336k
  pb.set_history_cutoff(history_cutoff_.ToUint64());
42
336k
  if (hybrid_time_filter_.is_valid()) {
43
24
    pb.set_hybrid_time_filter(hybrid_time_filter_.ToUint64());
44
24
  }
45
336k
  pb.set_max_value_level_ttl_expiration_time(max_value_level_ttl_expiration_time_.ToUint64());
46
336k
  any->PackFrom(pb);
47
336k
}
48
49
34.2k
void ConsensusFrontier::FromPB(const google::protobuf::Any& any) {
50
34.2k
  ConsensusFrontierPB pb;
51
34.2k
  any.UnpackTo(&pb);
52
34.2k
  op_id_ = OpId::FromPB(pb.op_id());
53
34.2k
  hybrid_time_ = HybridTime(pb.hybrid_time());
54
34.2k
  history_cutoff_ = NormalizeHistoryCutoff(HybridTime(pb.history_cutoff()));
55
34.2k
  if (pb.has_hybrid_time_filter()) {
56
17
    hybrid_time_filter_ = HybridTime(pb.hybrid_time_filter());
57
34.2k
  } else {
58
34.2k
    hybrid_time_filter_ = HybridTime();
59
34.2k
  }
60
34.2k
  max_value_level_ttl_expiration_time_ =
61
34.2k
      HybridTime::FromPB(pb.max_value_level_ttl_expiration_time());
62
34.2k
}
63
64
0
void ConsensusFrontier::FromOpIdPBDeprecated(const OpIdPB& pb) {
65
0
  op_id_ = OpId::FromPB(pb);
66
0
}
67
68
15.5k
std::string ConsensusFrontier::ToString() const {
69
15.5k
  return YB_CLASS_TO_STRING(
70
15.5k
      op_id, hybrid_time, history_cutoff, hybrid_time_filter, max_value_level_ttl_expiration_time);
71
15.5k
}
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
19.1k
    const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) {
81
19.1k
  if (!this_value || 
!updated_value15.3k
) {
82
    // If any of the two values is undefined, we don't treat this as an error.
83
3.85k
    return true;
84
3.85k
  }
85
15.3k
  switch (update_type) {
86
15.3k
    case rocksdb::UpdateUserValueType::kLargest:
87
15.3k
      return updated_value >= this_value;
88
12
    case rocksdb::UpdateUserValueType::kSmallest:
89
12
      return updated_value <= this_value;
90
15.3k
  }
91
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
92
0
}
consensus_frontier.cc:bool yb::docdb::(anonymous namespace)::IsUpdateValidForField<yb::OpId>(yb::OpId const&, yb::OpId const&, rocksdb::UpdateUserValueType)
Line
Count
Source
80
9.59k
    const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) {
81
9.59k
  if (!this_value || 
!updated_value7.67k
) {
82
    // If any of the two values is undefined, we don't treat this as an error.
83
1.92k
    return true;
84
1.92k
  }
85
7.66k
  switch (update_type) {
86
7.66k
    case rocksdb::UpdateUserValueType::kLargest:
87
7.66k
      return updated_value >= this_value;
88
7
    case rocksdb::UpdateUserValueType::kSmallest:
89
7
      return updated_value <= this_value;
90
7.66k
  }
91
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
92
0
}
consensus_frontier.cc:bool yb::docdb::(anonymous namespace)::IsUpdateValidForField<yb::HybridTime>(yb::HybridTime const&, yb::HybridTime const&, rocksdb::UpdateUserValueType)
Line
Count
Source
80
9.58k
    const T& this_value, const T& updated_value, rocksdb::UpdateUserValueType update_type) {
81
9.58k
  if (!this_value || 
!updated_value7.66k
) {
82
    // If any of the two values is undefined, we don't treat this as an error.
83
1.92k
    return true;
84
1.92k
  }
85
7.66k
  switch (update_type) {
86
7.65k
    case rocksdb::UpdateUserValueType::kLargest:
87
7.65k
      return updated_value >= this_value;
88
5
    case rocksdb::UpdateUserValueType::kSmallest:
89
5
      return updated_value <= this_value;
90
7.66k
  }
91
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
92
0
}
93
94
template<typename T>
95
void UpdateField(
96
92.4M
    T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) {
97
92.4M
  switch (update_type) {
98
46.2M
    case rocksdb::UpdateUserValueType::kLargest:
99
46.2M
      this_value->MakeAtLeast(new_value);
100
46.2M
      return;
101
46.1M
    case rocksdb::UpdateUserValueType::kSmallest:
102
46.1M
      this_value->MakeAtMost(new_value);
103
46.1M
      return;
104
92.4M
  }
105
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
106
0
}
consensus_frontier.cc:void yb::docdb::(anonymous namespace)::UpdateField<yb::OpId>(yb::OpId*, yb::OpId const&, rocksdb::UpdateUserValueType)
Line
Count
Source
96
23.1M
    T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) {
97
23.1M
  switch (update_type) {
98
11.5M
    case rocksdb::UpdateUserValueType::kLargest:
99
11.5M
      this_value->MakeAtLeast(new_value);
100
11.5M
      return;
101
11.5M
    case rocksdb::UpdateUserValueType::kSmallest:
102
11.5M
      this_value->MakeAtMost(new_value);
103
11.5M
      return;
104
23.1M
  }
105
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
106
0
}
consensus_frontier.cc:void yb::docdb::(anonymous namespace)::UpdateField<yb::HybridTime>(yb::HybridTime*, yb::HybridTime const&, rocksdb::UpdateUserValueType)
Line
Count
Source
96
69.2M
    T* this_value, const T& new_value, rocksdb::UpdateUserValueType update_type) {
97
69.2M
  switch (update_type) {
98
34.6M
    case rocksdb::UpdateUserValueType::kLargest:
99
34.6M
      this_value->MakeAtLeast(new_value);
100
34.6M
      return;
101
34.6M
    case rocksdb::UpdateUserValueType::kSmallest:
102
34.6M
      this_value->MakeAtMost(new_value);
103
34.6M
      return;
104
69.2M
  }
105
0
  FATAL_INVALID_ENUM_VALUE(rocksdb::UpdateUserValueType, update_type);
106
0
}
107
108
} // anonymous namespace
109
110
void ConsensusFrontier::Update(
111
23.1M
    const rocksdb::UserFrontier& pre_rhs, rocksdb::UpdateUserValueType update_type) {
112
23.1M
  const ConsensusFrontier& rhs = down_cast<const ConsensusFrontier&>(pre_rhs);
113
23.1M
  UpdateField(&op_id_, rhs.op_id_, update_type);
114
23.1M
  UpdateField(&hybrid_time_, rhs.hybrid_time_, update_type);
115
23.1M
  UpdateField(&history_cutoff_, rhs.history_cutoff_, update_type);
116
  // Reset filter after compaction.
117
23.1M
  hybrid_time_filter_ = HybridTime();
118
23.1M
  UpdateField(&max_value_level_ttl_expiration_time_,
119
23.1M
      rhs.max_value_level_ttl_expiration_time_, update_type);
120
23.1M
}
121
122
12.5M
Slice ConsensusFrontier::Filter() const {
123
12.5M
  return hybrid_time_filter_.is_valid()
124
12.5M
      ? 
Slice(pointer_cast<const char*>(&hybrid_time_filter_), sizeof(hybrid_time_filter_))80
125
12.5M
      : 
Slice()12.5M
;
126
12.5M
}
127
128
bool ConsensusFrontier::IsUpdateValid(
129
9.59k
    const rocksdb::UserFrontier& pre_rhs, rocksdb::UpdateUserValueType update_type) const {
130
9.59k
  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
9.59k
  return IsUpdateValidForField(op_id_, rhs.op_id_, update_type) &&
136
9.59k
         
IsUpdateValidForField(hybrid_time_, rhs.hybrid_time_, update_type)9.58k
;
137
9.59k
}
138
139
} // namespace docdb
140
} // namespace yb