YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/consensus/log_anchor_registry.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#include "yb/consensus/log_anchor_registry.h"
33
34
#include <mutex>
35
#include <string>
36
37
#include "yb/consensus/opid_util.h"
38
39
namespace yb {
40
namespace log {
41
42
using consensus::kInvalidOpIdIndex;
43
using std::pair;
44
using std::string;
45
using strings::Substitute;
46
using strings::SubstituteAndAppend;
47
48
89.1k
LogAnchorRegistry::LogAnchorRegistry() {
49
89.1k
}
50
51
47.5k
LogAnchorRegistry::~LogAnchorRegistry() {
52
47.5k
  CHECK(anchors_.empty());
53
47.5k
}
54
55
void LogAnchorRegistry::Register(int64_t log_index,
56
                                 const string& owner,
57
1.52k
                                 LogAnchor* anchor) {
58
1.52k
  std::lock_guard<simple_spinlock> l(lock_);
59
1.52k
  RegisterUnlocked(log_index, owner, anchor);
60
1.52k
}
61
62
Status LogAnchorRegistry::UpdateRegistration(int64_t log_index,
63
1.46k
                                             LogAnchor* anchor) {
64
1.46k
  std::lock_guard<simple_spinlock> l(lock_);
65
1.46k
  RETURN_NOT_OK_PREPEND(UnregisterUnlocked(anchor),
66
1.46k
                        "Unable to swap registration, anchor not registered")
67
1.46k
  RegisterUnlocked(log_index, std::string(), anchor);
68
1.46k
  return Status::OK();
69
1.46k
}
70
71
55
Status LogAnchorRegistry::Unregister(LogAnchor* anchor) {
72
55
  std::lock_guard<simple_spinlock> l(lock_);
73
55
  return UnregisterUnlocked(anchor);
74
55
}
75
76
2.40k
Status LogAnchorRegistry::UnregisterIfAnchored(LogAnchor* anchor) {
77
2.40k
  std::lock_guard<simple_spinlock> l(lock_);
78
2.40k
  if (!anchor->is_registered) return Status::OK();
79
960
  return UnregisterUnlocked(anchor);
80
960
}
81
82
6.40M
Status LogAnchorRegistry::GetEarliestRegisteredLogIndex(int64_t* log_index) {
83
6.40M
  std::lock_guard<simple_spinlock> l(lock_);
84
6.40M
  auto iter = anchors_.begin();
85
6.40M
  if (iter == anchors_.end()) {
86
6.39M
    static Status no_anchors_status = STATUS(NotFound, "No anchors in registry");
87
6.39M
    return no_anchors_status;
88
6.39M
  }
89
90
  // Since this is a sorted map, the first element is the one we want.
91
9.05k
  *log_index = iter->first;
92
9.05k
  return Status::OK();
93
9.05k
}
94
95
1
size_t LogAnchorRegistry::GetAnchorCountForTests() const {
96
1
  std::lock_guard<simple_spinlock> l(lock_);
97
1
  return anchors_.size();
98
1
}
99
100
1
std::string LogAnchorRegistry::DumpAnchorInfo() const {
101
1
  string buf;
102
1
  std::lock_guard<simple_spinlock> l(lock_);
103
1
  MonoTime now = MonoTime::Now();
104
4
  for (const AnchorMultiMap::value_type& entry : anchors_) {
105
4
    const LogAnchor* anchor = entry.second;
106
4
    DCHECK(anchor->is_registered);
107
4
    if (!buf.empty()) buf += ", ";
108
4
    SubstituteAndAppend(&buf, "LogAnchor[index=$0, age=$1s, owner=$2]",
109
4
                        anchor->log_index,
110
4
                        now.GetDeltaSince(anchor->when_registered).ToSeconds(),
111
4
                        anchor->owner);
112
4
  }
113
1
  return buf;
114
1
}
115
116
void LogAnchorRegistry::RegisterUnlocked(int64_t log_index,
117
                                         const std::string& owner,
118
2.98k
                                         LogAnchor* anchor) {
119
2.98k
  DCHECK(anchor != nullptr);
120
2.98k
  DCHECK(!anchor->is_registered);
121
122
2.98k
  anchor->log_index = log_index;
123
2.98k
  if (!owner.empty()) { // Keep existing owner during registration update.
124
1.52k
    anchor->owner = owner;
125
1.52k
  }
126
2.98k
  anchor->is_registered = true;
127
2.98k
  anchor->when_registered = MonoTime::Now();
128
2.98k
  AnchorMultiMap::value_type value(log_index, anchor);
129
2.98k
  anchors_.insert(value);
130
2.98k
}
131
132
2.47k
Status LogAnchorRegistry::UnregisterUnlocked(LogAnchor* anchor) {
133
2.47k
  DCHECK(anchor != nullptr);
134
2.47k
  DCHECK(anchor->is_registered);
135
136
2.47k
  auto iter = anchors_.find(anchor->log_index);
137
2.48k
  while (iter != anchors_.end()) {
138
2.48k
    if (iter->second == anchor) {
139
2.47k
      anchor->is_registered = false;
140
2.47k
      anchors_.erase(iter);
141
      // No need for the iterator to remain valid since we return here.
142
2.47k
      return Status::OK();
143
11
    } else {
144
11
      ++iter;
145
11
    }
146
2.48k
  }
147
18.4E
  return STATUS(NotFound, Substitute("Anchor with index $0 and owner $1 not found",
148
2.47k
                                     anchor->log_index, anchor->owner));
149
2.47k
}
150
151
LogAnchor::LogAnchor()
152
  : is_registered(false),
153
1.52k
    log_index(kInvalidOpIdIndex) {
154
1.52k
}
155
156
1.01k
LogAnchor::~LogAnchor() {
157
0
  CHECK(!is_registered) << "Attempted to destruct a registered LogAnchor";
158
1.01k
}
159
160
} // namespace log
161
} // namespace yb