summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-08-09 17:36:52 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2023-08-10 09:08:09 +0000
commitaa9cfaf526fa4cd0859dfaf47e50d5e02268161b (patch)
tree2a049970c7b1075c044d89df624d947ef1a4d217
parent16ade10496858b0046e45d44052170be381e503f (diff)
Avoid copying the ideal state out from the ideal state bundle.
It is just used as a const reference.
-rw-r--r--storage/src/tests/distributor/statecheckerstest.cpp34
-rw-r--r--storage/src/vespa/storage/distributor/ideal_service_layer_nodes_bundle.h6
-rw-r--r--storage/src/vespa/storage/distributor/statechecker.cpp10
-rw-r--r--storage/src/vespa/storage/distributor/statechecker.h8
-rw-r--r--storage/src/vespa/storage/distributor/statecheckers.cpp216
5 files changed, 89 insertions, 185 deletions
diff --git a/storage/src/tests/distributor/statecheckerstest.cpp b/storage/src/tests/distributor/statecheckerstest.cpp
index 16854cd63c6..cd64d81774e 100644
--- a/storage/src/tests/distributor/statecheckerstest.cpp
+++ b/storage/src/tests/distributor/statecheckerstest.cpp
@@ -1383,9 +1383,8 @@ std::string StateCheckersTest::testGarbageCollection(
getBucketDatabase().update(e);
NodeMaintenanceStatsTracker statsTracker;
- StateChecker::Context c(node_context(), operation_context(),
- getDistributorBucketSpace(), statsTracker,
- makeDocumentBucket(e.getBucketId()));
+ StateChecker::Context c(node_context(), operation_context(), getDistributorBucketSpace(),
+ statsTracker, makeDocumentBucket(e.getBucketId()));
getClock().setAbsoluteTimeInSeconds(nowTimestamp);
return testStateChecker(checker, c, false, PendingMessage(), includePriority, includeSchedulingPri);
}
@@ -1394,38 +1393,29 @@ TEST_F(StateCheckersTest, garbage_collection) {
// BucketId(17, 0) has id (and thus 'hash') 0x4400000000000000. With a
// check interval modulo of 3600, this implies a start point of 848.
- EXPECT_EQ("NO OPERATIONS GENERATED",
- testGarbageCollection(900, 3600 + 847, 3600));
+ EXPECT_EQ("NO OPERATIONS GENERATED", testGarbageCollection(900, 3600 + 847, 3600));
- EXPECT_EQ("[Needs garbage collection: Last check at 900, current time 4448, "
- "configured interval 3600]",
+ EXPECT_EQ("[Needs garbage collection: Last check at 900, current time 4448, configured interval 3600]",
testGarbageCollection(900, 3600 + 848, 3600));
- EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, "
- "configured interval 3600]",
+ EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, configured interval 3600]",
testGarbageCollection(3, 4000, 3600));
// GC start point 3648.
- EXPECT_EQ("NO OPERATIONS GENERATED",
- testGarbageCollection(3, 3647, 8000));
+ EXPECT_EQ("NO OPERATIONS GENERATED", testGarbageCollection(3, 3647, 8000));
- EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, "
- "configured interval 3600]",
+ EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, configured interval 3600]",
testGarbageCollection(3, 4000, 3600));
// GC explicitly disabled.
- EXPECT_EQ("NO OPERATIONS GENERATED",
- testGarbageCollection(3, 4000, 0));
+ EXPECT_EQ("NO OPERATIONS GENERATED", testGarbageCollection(3, 4000, 0));
- EXPECT_EQ("NO OPERATIONS GENERATED",
- testGarbageCollection(3, 3, 1));
+ EXPECT_EQ("NO OPERATIONS GENERATED", testGarbageCollection(3, 3, 1));
- EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, "
- "configured interval 300] (pri 200)",
+ EXPECT_EQ("[Needs garbage collection: Last check at 3, current time 4000, configured interval 300] (pri 200)",
testGarbageCollection(3, 4000, 300, 1, true));
- EXPECT_EQ("NO OPERATIONS GENERATED",
- testGarbageCollection(3850, 4000, 300, 1));
+ EXPECT_EQ("NO OPERATIONS GENERATED", testGarbageCollection(3850, 4000, 300, 1));
}
TEST_F(StateCheckersTest, gc_ops_are_prioritized_with_low_priority_category) {
@@ -1597,7 +1587,7 @@ TEST_F(StateCheckersTest, context_populates_ideal_state_containers) {
StateChecker::Context c(node_context(), operation_context(),
getDistributorBucketSpace(), statsTracker, makeDocumentBucket({17, 0}));
- ASSERT_THAT(c.idealState, ElementsAre(1, 3));
+ ASSERT_THAT(c.idealState(), ElementsAre(1, 3));
// TODO replace with UnorderedElementsAre once we can build gmock without issues
std::vector<uint16_t> ideal_state(c.unorderedIdealState.begin(), c.unorderedIdealState.end());
std::sort(ideal_state.begin(), ideal_state.end());
diff --git a/storage/src/vespa/storage/distributor/ideal_service_layer_nodes_bundle.h b/storage/src/vespa/storage/distributor/ideal_service_layer_nodes_bundle.h
index 8f9cb8e14ec..bb2e2c15996 100644
--- a/storage/src/vespa/storage/distributor/ideal_service_layer_nodes_bundle.h
+++ b/storage/src/vespa/storage/distributor/ideal_service_layer_nodes_bundle.h
@@ -27,9 +27,9 @@ public:
void set_available_nonretired_or_maintenance_nodes(std::vector<uint16_t> available_nonretired_or_maintenance_nodes) {
_available_nonretired_or_maintenance_nodes = std::move(available_nonretired_or_maintenance_nodes);
}
- const std::vector<uint16_t> & get_available_nodes() const { return _available_nodes; }
- const std::vector<uint16_t> & get_available_nonretired_nodes() const { return _available_nonretired_nodes; }
- const std::vector<uint16_t> & get_available_nonretired_or_maintenance_nodes() const {
+ const std::vector<uint16_t> & get_available_nodes() const noexcept { return _available_nodes; }
+ const std::vector<uint16_t> & get_available_nonretired_nodes() const noexcept { return _available_nonretired_nodes; }
+ const std::vector<uint16_t> & get_available_nonretired_or_maintenance_nodes() const noexcept {
return _available_nonretired_or_maintenance_nodes;
}
};
diff --git a/storage/src/vespa/storage/distributor/statechecker.cpp b/storage/src/vespa/storage/distributor/statechecker.cpp
index 27a60b73716..96ad3b46e5d 100644
--- a/storage/src/vespa/storage/distributor/statechecker.cpp
+++ b/storage/src/vespa/storage/distributor/statechecker.cpp
@@ -51,13 +51,11 @@ public:
StateChecker::Result
StateChecker::Result::noMaintenanceNeeded()
{
- return Result(std::unique_ptr<ResultImpl>());
+ return Result({});
}
StateChecker::Result
-StateChecker::Result::createStoredResult(
- IdealStateOperation::UP operation,
- MaintenancePriority::Priority priority)
+StateChecker::Result::createStoredResult(IdealStateOperation::UP operation, MaintenancePriority::Priority priority)
{
return Result(std::make_unique<StoredResultImpl>(std::move(operation), MaintenancePriority(priority)));
}
@@ -74,14 +72,14 @@ StateChecker::Context::Context(const DistributorNodeContext& node_ctx_in,
distributorConfig(op_ctx_in.distributor_config()),
distribution(distributorBucketSpace.getDistribution()),
gcTimeCalculator(op_ctx_in.bucket_id_hasher(), distributorConfig.getGarbageCollectionInterval()),
+ idealStateBundle(distributorBucketSpace.get_ideal_service_layer_nodes_bundle(bucket.getBucketId())),
node_ctx(node_ctx_in),
op_ctx(op_ctx_in),
db(distributorBucketSpace.getBucketDatabase()),
stats(statsTracker),
merges_inhibited_in_bucket_space(distributorBucketSpace.merges_inhibited())
{
- idealState = distributorBucketSpace.get_ideal_service_layer_nodes_bundle(bucket.getBucketId()).get_available_nonretired_or_maintenance_nodes();
- unorderedIdealState.insert(idealState.begin(), idealState.end());
+ unorderedIdealState.insert(idealState().begin(), idealState().end());
}
StateChecker::Context::~Context() = default;
diff --git a/storage/src/vespa/storage/distributor/statechecker.h b/storage/src/vespa/storage/distributor/statechecker.h
index 830e05676be..ef50c78f068 100644
--- a/storage/src/vespa/storage/distributor/statechecker.h
+++ b/storage/src/vespa/storage/distributor/statechecker.h
@@ -2,6 +2,7 @@
#pragma once
#include "bucketgctimecalculator.h"
+#include "ideal_service_layer_nodes_bundle.h"
#include <vespa/storage/distributor/maintenance/maintenancepriority.h>
#include <vespa/storage/distributor/operations/idealstate/idealstateoperation.h>
#include <vespa/storage/common/storagecomponent.h>
@@ -73,7 +74,7 @@ public:
// need to both know the actual order (activation prioritization etc) as
// well as have the ability to quickly check if a node is in an ideal
// location.
- std::vector<uint16_t> idealState;
+ const IdealServiceLayerNodesBundle & idealStateBundle;
vespalib::hash_set<uint16_t> unorderedIdealState;
const DistributorNodeContext& node_ctx;
@@ -82,9 +83,8 @@ public:
NodeMaintenanceStatsTracker& stats;
const bool merges_inhibited_in_bucket_space;
- const BucketDatabase::Entry& getSiblingEntry() const noexcept {
- return siblingEntry;
- }
+ const BucketDatabase::Entry& getSiblingEntry() const noexcept { return siblingEntry; }
+ const std::vector<uint16_t> & idealState() const noexcept { return idealStateBundle.get_available_nonretired_or_maintenance_nodes(); }
document::Bucket getBucket() const noexcept { return bucket; }
document::BucketId getBucketId() const noexcept { return bucket.getBucketId(); }
diff --git a/storage/src/vespa/storage/distributor/statecheckers.cpp b/storage/src/vespa/storage/distributor/statecheckers.cpp
index fe1f4422c45..56247d744bf 100644
--- a/storage/src/vespa/storage/distributor/statecheckers.cpp
+++ b/storage/src/vespa/storage/distributor/statecheckers.cpp
@@ -27,9 +27,7 @@ SplitBucketStateChecker::validForSplit(Context& c)
{
// Can't split if we have no nodes.
if (c.entry->getNodeCount() == 0) {
- LOG(spam,
- "Can't split bucket %s, since it has no copies",
- c.bucket.toString().c_str());
+ LOG(spam, "Can't split bucket %s, since it has no copies", c.bucket.toString().c_str());
return false;
}
@@ -83,33 +81,21 @@ SplitBucketStateChecker::getBucketSizeRelativeToMax(Context& c)
}
StateChecker::Result
-SplitBucketStateChecker::generateMinimumBucketSplitOperation(
- Context& c)
+SplitBucketStateChecker::generateMinimumBucketSplitOperation(Context& c)
{
- auto so = std::make_unique<SplitOperation>(
- c.node_ctx,
- BucketAndNodes(c.getBucket(), c.entry->getNodes()),
- c.distributorConfig.getMinimalBucketSplit(),
- 0,
- 0);
+ auto so = std::make_unique<SplitOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), c.entry->getNodes()),
+ c.distributorConfig.getMinimalBucketSplit(), 0, 0);
so->setPriority(c.distributorConfig.getMaintenancePriorities().splitDistributionBits);
- so->setDetailedReason(
- "[Splitting bucket because the current system size requires "
- "a higher minimum split bit]");
+ so->setDetailedReason("[Splitting bucket because the current system size requires a higher minimum split bit]");
return Result::createStoredResult(std::move(so), MaintenancePriority::MEDIUM);
}
StateChecker::Result
-SplitBucketStateChecker::generateMaxSizeExceededSplitOperation(
- Context& c)
+SplitBucketStateChecker::generateMaxSizeExceededSplitOperation(Context& c)
{
- auto so = std::make_unique<SplitOperation>(
- c.node_ctx,
- BucketAndNodes(c.getBucket(), c.entry->getNodes()),
- 58,
- c.distributorConfig.getSplitCount(),
- c.distributorConfig.getSplitSize());
+ auto so = std::make_unique<SplitOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), c.entry->getNodes()), 58,
+ c.distributorConfig.getSplitCount(), c.distributorConfig.getSplitSize());
so->setPriority(c.distributorConfig.getMaintenancePriorities().splitLargeBucket);
@@ -160,8 +146,7 @@ JoinBucketsStateChecker::isFirstSibling(const document::BucketId& bucketId)
namespace {
bool
-equalNodeSet(const std::vector<uint16_t>& idealState,
- const BucketDatabase::Entry& dbEntry)
+equalNodeSet(const std::vector<uint16_t>& idealState, const BucketDatabase::Entry& dbEntry)
{
if (idealState.size() != dbEntry->getNodeCount()) {
return false;
@@ -179,12 +164,10 @@ equalNodeSet(const std::vector<uint16_t>& idealState,
bool
bucketAndSiblingReplicaLocationsEqualIdealState(const StateChecker::Context& context)
{
- if (!equalNodeSet(context.idealState, context.entry)) {
+ if (!equalNodeSet(context.idealState(), context.entry)) {
return false;
}
- std::vector<uint16_t> siblingIdealState(
- context.distribution.getIdealStorageNodes(
- context.systemState, context.siblingBucket));
+ std::vector<uint16_t> siblingIdealState = context.distribution.getIdealStorageNodes(context.systemState, context.siblingBucket);
if (!equalNodeSet(siblingIdealState, context.siblingEntry)) {
return false;
}
@@ -213,41 +196,29 @@ JoinBucketsStateChecker::siblingsAreInSync(const Context& context)
const auto& siblingEntry(context.siblingEntry);
if (entry->getNodeCount() != siblingEntry->getNodeCount()) {
- LOG(spam,
- "Not joining bucket %s because sibling bucket %s had different "
- "node count",
- context.bucket.toString().c_str(),
- context.siblingBucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because sibling bucket %s had different node count",
+ context.bucket.toString().c_str(), context.siblingBucket.toString().c_str());
return false;
}
bool siblingsCoLocated = true;
for (uint32_t i = 0; i < entry->getNodeCount(); ++i) {
- if (entry->getNodeRef(i).getNode()
- != siblingEntry->getNodeRef(i).getNode())
- {
+ if (entry->getNodeRef(i).getNode() != siblingEntry->getNodeRef(i).getNode()) {
siblingsCoLocated = false;
break;
}
}
if (!siblingsCoLocated && !inconsistentJoinIsAllowed(context)) {
- LOG(spam,
- "Not joining bucket %s because sibling bucket %s "
- "does not have the same node set, or inconsistent joins cannot be "
- "performed either due to config or because replicas were not in "
- "their ideal location",
- context.bucket.toString().c_str(),
- context.siblingBucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because sibling bucket %s does not have the same node set, or inconsistent "
+ "joins cannot be performed either due to config or because replicas were not in their ideal location",
+ context.bucket.toString().c_str(), context.siblingBucket.toString().c_str());
return false;
}
if (!entry->validAndConsistent() || !siblingEntry->validAndConsistent()) {
- LOG(spam,
- "Not joining bucket %s because it or %s is out of sync "
- "and syncing it may cause it to become too large",
- context.bucket.toString().c_str(),
- context.siblingBucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because it or %s is out of sync and syncing it may cause it to become too large",
+ context.bucket.toString().c_str(), context.siblingBucket.toString().c_str());
return false;
}
@@ -291,9 +262,8 @@ contextBucketHasTooManyReplicas(const StateChecker::Context& c)
bool
bucketAtDistributionBitLimit(const document::BucketId& bucket, const StateChecker::Context& c)
{
- return (bucket.getUsedBits() <= std::max(
- uint32_t(c.systemState.getDistributionBitCount()),
- c.distributorConfig.getMinimalBucketSplit()));
+ return (bucket.getUsedBits() <= std::max(uint32_t(c.systemState.getDistributionBitCount()),
+ c.distributorConfig.getMinimalBucketSplit()));
}
}
@@ -302,31 +272,23 @@ bool
JoinBucketsStateChecker::shouldJoin(const Context& c)
{
if (c.entry->getNodeCount() == 0) {
- LOG(spam, "Not joining bucket %s because it has no nodes",
- c.bucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because it has no nodes", c.bucket.toString().c_str());
return false;
}
if (contextBucketHasTooManyReplicas(c)) {
- LOG(spam, "Not joining %s because it has too high replication level",
- c.bucket.toString().c_str());
+ LOG(spam, "Not joining %s because it has too high replication level", c.bucket.toString().c_str());
return false;
}
if (c.distributorConfig.getJoinSize() == 0 && c.distributorConfig.getJoinCount() == 0) {
- LOG(spam, "Not joining bucket %s because join is disabled",
- c.bucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because join is disabled", c.bucket.toString().c_str());
return false;
}
if (bucketAtDistributionBitLimit(c.getBucketId(), c)) {
- LOG(spam,
- "Not joining bucket %s because it is below the min split "
- "count (config: %u, cluster state: %u, bucket has: %u)",
- c.bucket.toString().c_str(),
- c.distributorConfig.getMinimalBucketSplit(),
- c.systemState.getDistributionBitCount(),
- c.getBucketId().getUsedBits());
+ LOG(spam, "Not joining bucket %s because it is below the min split count (config: %u, cluster state: %u, bucket has: %u)",
+ c.bucket.toString().c_str(), c.distributorConfig.getMinimalBucketSplit(), c.systemState.getDistributionBitCount(), c.getBucketId().getUsedBits());
return false;
}
@@ -336,11 +298,8 @@ JoinBucketsStateChecker::shouldJoin(const Context& c)
if (c.getSiblingEntry().valid()) {
if (!isFirstSibling(c.getBucketId())) {
- LOG(spam,
- "Not joining bucket %s because it is the second sibling of "
- "%s and not the first",
- c.bucket.toString().c_str(),
- c.siblingBucket.toString().c_str());
+ LOG(spam, "Not joining bucket %s because it is the second sibling of %s and not the first",
+ c.bucket.toString().c_str(), c.siblingBucket.toString().c_str());
return false;
}
if (!siblingsAreInSync(c)) {
@@ -463,24 +422,13 @@ JoinBucketsStateChecker::check(Context& c) const
sourceBuckets.push_back(c.getBucketId());
}
sourceBuckets.push_back(c.getBucketId());
- auto op = std::make_unique<JoinOperation>(
- c.node_ctx,
- BucketAndNodes(joinedBucket, c.entry->getNodes()),
- sourceBuckets);
+ auto op = std::make_unique<JoinOperation>(c.node_ctx, BucketAndNodes(joinedBucket, c.entry->getNodes()), sourceBuckets);
op->setPriority(c.distributorConfig.getMaintenancePriorities().joinBuckets);
vespalib::asciistream ost;
- ost << "[Joining buckets "
- << sourceBuckets[1].toString()
- << " and " << sourceBuckets[0].toString()
- << " because their size ("
- << getTotalUsedFileSize(c)
- << " bytes, "
- << getTotalMetaCount(c)
- << " docs) is less than the configured limit of ("
- << c.distributorConfig.getJoinSize()
- << ", "
- << c.distributorConfig.getJoinCount()
- << ")";
+ ost << "[Joining buckets " << sourceBuckets[1].toString() << " and " << sourceBuckets[0].toString()
+ << " because their size (" << getTotalUsedFileSize(c) << " bytes, "
+ << getTotalMetaCount(c) << " docs) is less than the configured limit of ("
+ << c.distributorConfig.getJoinSize() << ", " << c.distributorConfig.getJoinCount() << ")";
op->setDetailedReason(ost.str());
@@ -516,8 +464,7 @@ vespalib::string
SplitInconsistentStateChecker::getReason(const document::BucketId& bucketId, const std::vector<BucketDatabase::Entry>& entries)
{
vespalib::asciistream reason;
- reason << "[Bucket is inconsistently split (list includes "
- << vespalib::hex << "0x" << bucketId.getId();
+ reason << "[Bucket is inconsistently split (list includes " << vespalib::hex << "0x" << bucketId.getId();
for (uint32_t i = 0, found = 0; i < entries.size() && found < 3; i++) {
if (!(entries[i].getBucketId() == bucketId)) {
@@ -530,10 +477,7 @@ SplitInconsistentStateChecker::getReason(const document::BucketId& bucketId, con
reason << " and " << vespalib::dec << entries.size() - 4 << " others";
}
- reason << ") Splitting it to improve the problem (max used bits "
- << vespalib::dec
- << getHighestUsedBits(entries)
- << ")]";
+ reason << ") Splitting it to improve the problem (max used bits " << vespalib::dec << getHighestUsedBits(entries) << ")]";
return reason.str();
}
@@ -559,12 +503,8 @@ SplitInconsistentStateChecker::check(Context& c) const
return Result::noMaintenanceNeeded();
}
- auto op = std::make_unique<SplitOperation>(
- c.node_ctx,
- BucketAndNodes(c.getBucket(), c.entry->getNodes()),
- getHighestUsedBits(c.entries),
- 0,
- 0);
+ auto op = std::make_unique<SplitOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), c.entry->getNodes()),
+ getHighestUsedBits(c.entries), 0, 0);
op->setPriority(c.distributorConfig.getMaintenancePriorities().splitInconsistentBucket);
op->setDetailedReason(getReason(c.getBucketId(), c.entries));
@@ -576,8 +516,7 @@ namespace {
bool containsMaintenanceNode(const std::vector<uint16_t>& ideal, const StateChecker::Context& c)
{
for (uint16_t n : ideal) {
- lib::Node node(lib::NodeType::STORAGE, n);
- if (c.systemState.getNodeState(node).getState() == lib::State::MAINTENANCE) {
+ if (c.systemState.getNodeState(lib::Node(lib::NodeType::STORAGE, n)).getState() == lib::State::MAINTENANCE) {
return true;
}
}
@@ -588,9 +527,8 @@ bool ideal_node_is_unavailable_in_pending_state(const StateChecker::Context& c)
if (!c.pending_cluster_state) {
return false;
}
- for (uint16_t n : c.idealState) {
- lib::Node node(lib::NodeType::STORAGE, n);
- if (!c.pending_cluster_state->getNodeState(node).getState().oneOf("uir")){
+ for (uint16_t n : c.idealState()) {
+ if (!c.pending_cluster_state->getNodeState(lib::Node(lib::NodeType::STORAGE, n)).getState().oneOf("uir")){
return true;
}
}
@@ -598,9 +536,7 @@ bool ideal_node_is_unavailable_in_pending_state(const StateChecker::Context& c)
}
bool
-consistentApartFromEmptyBucketsInNonIdealLocationAndInvalidEntries(
- const std::vector<uint16_t>& idealNodes,
- const BucketInfo& entry)
+consistentApartFromEmptyBucketsInNonIdealLocationAndInvalidEntries(const std::vector<uint16_t>& idealNodes, const BucketInfo& entry)
{
api::BucketInfo info;
for (uint32_t i=0, n=entry.getNodeCount(); i<n; ++i) {
@@ -730,7 +666,7 @@ addStatisticsForNonIdealNodes(const StateChecker::Context& c, bool missingReplic
{
// Common case is that ideal state == actual state with no missing replicas.
// If so, do nothing.
- if (!missingReplica && (c.idealState.size() == c.entry->getNodeCount())) {
+ if (!missingReplica && (c.idealState().size() == c.entry->getNodeCount())) {
return;
}
for (uint32_t j = 0; j < c.entry->getNodeCount(); ++j) {
@@ -753,26 +689,23 @@ checkForNodesMissingFromIdealState(StateChecker::Context& c)
// Check if we need to add copies to get to ideal state.
if (!c.entry->emptyAndConsistent()) {
bool hasMissingReplica = false;
- for (uint32_t i = 0; i < c.idealState.size(); i++) {
+ for (uint16_t node : c.idealState()) {
bool found = false;
for (uint32_t j = 0; j < c.entry->getNodeCount(); j++) {
- if (c.entry->getNodeRef(j).getNode() == c.idealState[i]) {
+ if (c.entry->getNodeRef(j).getNode() == node) {
found = true;
break;
}
}
if (!found) {
- const DistributorConfiguration::MaintenancePriorities& mp(
- c.distributorConfig.getMaintenancePriorities());
- if (c.idealState.size() > c.entry->getNodeCount()) {
- ret.markMissingReplica(c.idealState[i],
- mp.mergeTooFewCopies);
+ const auto & mp = c.distributorConfig.getMaintenancePriorities();
+ if (c.idealState().size() > c.entry->getNodeCount()) {
+ ret.markMissingReplica(node, mp.mergeTooFewCopies);
} else {
- ret.markMoveToIdealLocation(c.idealState[i],
- mp.mergeMoveToIdealNode);
+ ret.markMoveToIdealLocation(node,mp.mergeMoveToIdealNode);
}
- c.stats.incCopyingIn(c.idealState[i], c.getBucketSpace());
+ c.stats.incCopyingIn(node, c.getBucketSpace());
hasMissingReplica = true;
}
}
@@ -795,12 +728,8 @@ MergeNodes
checkIfBucketsAreOutOfSyncAndNeedMerging(StateChecker::Context& c)
{
MergeNodes ret;
- if (!consistentApartFromEmptyBucketsInNonIdealLocationAndInvalidEntries(
- c.idealState,
- c.entry.getBucketInfo()))
- {
- auto pri(c.distributorConfig.getMaintenancePriorities()
- .mergeOutOfSyncCopies);
+ if (!consistentApartFromEmptyBucketsInNonIdealLocationAndInvalidEntries(c.idealState(),c.entry.getBucketInfo())) {
+ auto pri(c.distributorConfig.getMaintenancePriorities().mergeOutOfSyncCopies);
ret.markOutOfSync(c, pri);
addStatisticsForOutOfSyncCopies(c);
}
@@ -839,7 +768,7 @@ SynchronizeAndMoveStateChecker::check(Context& c) const
if (isInconsistentlySplit(c)) {
return Result::noMaintenanceNeeded();
}
- if (containsMaintenanceNode(c.idealState, c)) {
+ if (containsMaintenanceNode(c.idealState(), c)) {
return Result::noMaintenanceNeeded();
}
if (ideal_node_is_unavailable_in_pending_state(c)) {
@@ -863,8 +792,7 @@ SynchronizeAndMoveStateChecker::check(Context& c) const
if ((c.getBucketSpace() == document::FixedBucketSpaces::default_space())
|| !c.distributorConfig.prioritize_global_bucket_merges())
{
- schedPri = (result.needsMoveOnly() ? MaintenancePriority::LOW
- : MaintenancePriority::MEDIUM);
+ schedPri = (result.needsMoveOnly() ? MaintenancePriority::LOW : MaintenancePriority::MEDIUM);
op->setPriority(result.priority());
} else {
// Since the default bucket space has a dependency on the global bucket space,
@@ -876,10 +804,8 @@ SynchronizeAndMoveStateChecker::check(Context& c) const
return Result::createStoredResult(std::move(op), schedPri);
} else {
- LOG(spam, "Bucket %s: No need for merge, as bucket is in consistent state "
- "(or inconsistent buckets are empty) %s",
- c.bucket.toString().c_str(),
- c.entry->toString().c_str());
+ LOG(spam, "Bucket %s: No need for merge, as bucket is in consistent state (or inconsistent buckets are empty) %s",
+ c.bucket.toString().c_str(), c.entry->toString().c_str());
return Result::noMaintenanceNeeded();
}
}
@@ -894,7 +820,7 @@ DeleteExtraCopiesStateChecker::bucketHasNoData(const Context& c)
bool
DeleteExtraCopiesStateChecker::copyIsInIdealState(const BucketCopy& cp, const Context& c)
{
- return hasItem(c.idealState, cp.getNode());
+ return hasItem(c.idealState(), cp.getNode());
}
bool
@@ -910,9 +836,7 @@ DeleteExtraCopiesStateChecker::addToRemoveSet(
std::vector<uint16_t>& removedCopies,
vespalib::asciistream& reasons)
{
- reasons << "[Removing " << reasonForRemoval
- << " from node " << copyToRemove.getNode()
- << ']';
+ reasons << "[Removing " << reasonForRemoval << " from node " << copyToRemove.getNode() << ']';
removedCopies.push_back(copyToRemove.getNode());
}
@@ -980,7 +904,7 @@ DeleteExtraCopiesStateChecker::check(Context& c) const
}
// Maintain symmetry with merge; don't try to mess with nodes that have an
// ideal copy on a node set in maintenance mode.
- if (containsMaintenanceNode(c.idealState, c)) {
+ if (containsMaintenanceNode(c.idealState(), c)) {
return Result::noMaintenanceNeeded();
}
@@ -988,8 +912,7 @@ DeleteExtraCopiesStateChecker::check(Context& c) const
std::vector<uint16_t> removedCopies;
if (bucketHasNoData(c)) {
- reasons << "[Removing all copies since bucket is empty:"
- << c.entry->toString() << "]";
+ reasons << "[Removing all copies since bucket is empty:" << c.entry->toString() << "]";
for (uint32_t j = 0, cnt = c.entry->getNodeCount(); j < cnt; ++j) {
removedCopies.push_back(c.entry->getNodeRef(j).getNode());
@@ -1003,9 +926,7 @@ DeleteExtraCopiesStateChecker::check(Context& c) const
}
if (!removedCopies.empty()) {
- auto ro = std::make_unique<RemoveBucketOperation>(
- c.node_ctx,
- BucketAndNodes(c.getBucket(), removedCopies));
+ auto ro = std::make_unique<RemoveBucketOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), removedCopies));
ro->setPriority(c.distributorConfig.getMaintenancePriorities().deleteBucketCopy);
ro->setDetailedReason(reasons.str());
@@ -1029,7 +950,7 @@ BucketStateStateChecker::shouldSkipActivationDueToMaintenance(const ActiveList&
// If copy is not ready, we don't want to activate it if a node
// is set in maintenance. Doing so would imply that we want proton
// to start background indexing.
- return containsMaintenanceNode(c.idealState, c);
+ return containsMaintenanceNode(c.idealState(), c);
} // else: activation does not imply indexing, so we can safely do it at any time.
}
}
@@ -1057,9 +978,8 @@ BucketStateStateChecker::check(Context& c) const
return Result::noMaintenanceNeeded();
}
- ActiveList activeNodes(
- ActiveCopy::calculate(c.idealState, c.distribution, c.entry,
- c.distributorConfig.max_activation_inhibited_out_of_sync_groups()));
+ ActiveList activeNodes = ActiveCopy::calculate(c.idealState(), c.distribution, c.entry,
+ c.distributorConfig.max_activation_inhibited_out_of_sync_groups());
if (activeNodes.empty()) {
return Result::noMaintenanceNeeded();
}
@@ -1075,8 +995,7 @@ BucketStateStateChecker::check(Context& c) const
continue;
}
operationNodes.push_back(activeNodes[i]._nodeIndex);
- reason << "[Setting node " << activeNodes[i]._nodeIndex << " as active: "
- << activeNodes[i].getReason() << "]";
+ reason << "[Setting node " << activeNodes[i]._nodeIndex << " as active: " << activeNodes[i].getReason() << "]";
}
// Deactivate all copies that are currently marked as active.
@@ -1105,10 +1024,7 @@ BucketStateStateChecker::check(Context& c) const
for (uint32_t i=0; i<activeNodes.size(); ++i) {
activeNodeIndexes.push_back(activeNodes[i]._nodeIndex);
}
- auto op = std::make_unique<SetBucketStateOperation>(
- c.node_ctx,
- BucketAndNodes(c.getBucket(), operationNodes),
- activeNodeIndexes);
+ auto op = std::make_unique<SetBucketStateOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), operationNodes), activeNodeIndexes);
// If activeNodes > 1, we're dealing with a active-per-leaf group case and
// we currently always send high pri activations.
@@ -1134,7 +1050,7 @@ GarbageCollectionStateChecker::needs_garbage_collection(const Context& c, vespal
if (c.entry->getNodeCount() == 0) {
return false;
}
- if (containsMaintenanceNode(c.idealState, c)) {
+ if (containsMaintenanceNode(c.idealState(), c)) {
return false;
}
std::chrono::seconds lastRunAt(c.entry->getLastGarbageCollectionTime());