summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-08-11 10:02:21 +0200
committerGitHub <noreply@github.com>2023-08-11 10:02:21 +0200
commit906fa79d1f612d3a7813522717bdb0d8e1ab8f39 (patch)
treed65deb58452914175b4600f67ea2a2221d89d0b3
parenteac7928cf7ca9e9be4b47dcb3143d42d7e2dc6d2 (diff)
parent263d7febb37eab596036a56b6d48d0c544989c08 (diff)
Merge pull request #28022 from vespa-engine/balder/cheaper-split-nodes-into-leaf-groups
Balder/cheaper split nodes into leaf groups
-rw-r--r--storage/src/tests/distributor/distributor_stripe_test_util.cpp100
-rw-r--r--storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp70
-rw-r--r--storage/src/tests/distributor/top_level_distributor_test_util.cpp11
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketcopy.h20
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketinfo.cpp33
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketinfo.h49
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketinfo.hpp97
-rw-r--r--storage/src/vespa/storage/distributor/activecopy.cpp88
-rw-r--r--storage/src/vespa/storage/distributor/idealstatemanager.cpp67
-rw-r--r--storage/src/vespa/storage/distributor/idealstatemanager.h14
-rw-r--r--storage/src/vespa/storage/storageutil/distributorstatecache.h8
-rw-r--r--storage/src/vespa/storage/tools/getidealstate.cpp15
-rw-r--r--vdslib/src/tests/distribution/distributiontest.cpp123
-rw-r--r--vdslib/src/vespa/vdslib/distribution/distribution.cpp71
-rw-r--r--vdslib/src/vespa/vdslib/distribution/distribution.h78
15 files changed, 329 insertions, 515 deletions
diff --git a/storage/src/tests/distributor/distributor_stripe_test_util.cpp b/storage/src/tests/distributor/distributor_stripe_test_util.cpp
index 7a64eda28ff..6ececa39583 100644
--- a/storage/src/tests/distributor/distributor_stripe_test_util.cpp
+++ b/storage/src/tests/distributor/distributor_stripe_test_util.cpp
@@ -40,34 +40,22 @@ DistributorStripeTestUtil::createLinks()
_node = std::make_unique<TestDistributorApp>(_config.getConfigId());
_metrics = std::make_shared<DistributorMetricSet>();
_ideal_state_metrics = std::make_shared<IdealStateMetricSet>();
- _stripe = std::make_unique<DistributorStripe>(_node->getComponentRegister(),
- *_metrics,
- *_ideal_state_metrics,
- _node->node_identity(),
- _messageSender,
- *this,
- _done_initializing);
+ _stripe = std::make_unique<DistributorStripe>(_node->getComponentRegister(), *_metrics, *_ideal_state_metrics,
+ _node->node_identity(), _messageSender, *this, _done_initializing);
}
void
-DistributorStripeTestUtil::setup_stripe(int redundancy,
- int nodeCount,
- const std::string& systemState,
- uint32_t earlyReturn,
- bool requirePrimaryToBeWritten)
+DistributorStripeTestUtil::setup_stripe(int redundancy, int nodeCount, const std::string& systemState,
+ uint32_t earlyReturn, bool requirePrimaryToBeWritten)
{
setup_stripe(redundancy, nodeCount, lib::ClusterStateBundle(lib::ClusterState(systemState)), earlyReturn, requirePrimaryToBeWritten);
}
void
-DistributorStripeTestUtil::setup_stripe(int redundancy,
- int node_count,
- const lib::ClusterStateBundle& state,
- uint32_t early_return,
- bool require_primary_to_be_written)
+DistributorStripeTestUtil::setup_stripe(int redundancy, int node_count, const lib::ClusterStateBundle& state,
+ uint32_t early_return, bool require_primary_to_be_written)
{
- lib::Distribution::DistributionConfigBuilder config(
- lib::Distribution::getDefaultDistributionConfig(redundancy, node_count).get());
+ lib::Distribution::DistributionConfigBuilder config(lib::Distribution::getDefaultDistributionConfig(redundancy, node_count).get());
config.redundancy = redundancy;
config.initialRedundancy = early_return;
config.ensurePrimaryPersisted = require_primary_to_be_written;
@@ -93,8 +81,7 @@ DistributorStripeTestUtil::setup_stripe(int redundancy,
void
DistributorStripeTestUtil::set_redundancy(uint32_t redundancy)
{
- auto distribution = std::make_shared<lib::Distribution>(
- lib::Distribution::getDefaultDistributionConfig(redundancy, 100));
+ auto distribution = std::make_shared<lib::Distribution>(lib::Distribution::getDefaultDistributionConfig(redundancy, 100));
// Same rationale for not triggering a full distribution change as
// in setup_stripe() above
_node->getComponentRegister().setDistribution(distribution);
@@ -217,8 +204,7 @@ DistributorStripeTestUtil::getIdealStr(document::BucketId id, const lib::Cluster
}
std::vector<uint16_t> nodes;
- getDistribution().getIdealNodes(
- lib::NodeType::STORAGE, state, id, nodes);
+ getDistribution().getIdealNodes(lib::NodeType::STORAGE, state, id, nodes, "uim");
std::sort(nodes.begin(), nodes.end());
std::ostringstream ost;
ost << id << ": " << dumpVector(nodes);
@@ -226,8 +212,7 @@ DistributorStripeTestUtil::getIdealStr(document::BucketId id, const lib::Cluster
}
void
-DistributorStripeTestUtil::addIdealNodes(const lib::ClusterState& state,
- const document::BucketId& id)
+DistributorStripeTestUtil::addIdealNodes(const lib::ClusterState& state, const document::BucketId& id)
{
BucketDatabase::Entry entry = getBucket(id);
@@ -236,15 +221,11 @@ DistributorStripeTestUtil::addIdealNodes(const lib::ClusterState& state,
}
std::vector<uint16_t> res;
- getDistribution().getIdealNodes(
- lib::NodeType::STORAGE, state, id, res);
+ getDistribution().getIdealNodes(lib::NodeType::STORAGE, state, id, res, "uim");
for (uint32_t i = 0; i < res.size(); ++i) {
- if (state.getNodeState(lib::Node(lib::NodeType::STORAGE, res[i])).getState() !=
- lib::State::MAINTENANCE)
- {
- entry->addNode(BucketCopy(0, res[i], api::BucketInfo(1,1,1)),
- toVector<uint16_t>(0));
+ if (state.getNodeState(lib::Node(lib::NodeType::STORAGE, res[i])).getState() != lib::State::MAINTENANCE) {
+ entry->addNode(BucketCopy(0, res[i], api::BucketInfo(1,1,1)), toVector<uint16_t>(0));
}
}
@@ -292,10 +273,7 @@ DistributorStripeTestUtil::addNodesToBucketDB(const document::Bucket& bucket, co
}
uint16_t idx = atoi(tok2[0].data());
- BucketCopy node(
- 0,
- idx,
- info);
+ BucketCopy node(0, idx, info);
// Allow user to manually override trusted and active.
if (tok3.size() > flagsIdx && tok3[flagsIdx] == "t") {
@@ -309,44 +287,32 @@ DistributorStripeTestUtil::addNodesToBucketDB(const document::Bucket& bucket, co
}
void
-DistributorStripeTestUtil::addNodesToBucketDB(const document::BucketId& id,
- const std::string& nodeStr)
-{
+DistributorStripeTestUtil::addNodesToBucketDB(const document::BucketId& id, const std::string& nodeStr) {
addNodesToBucketDB(document::Bucket(makeBucketSpace(), id), nodeStr);
}
void
-DistributorStripeTestUtil::removeFromBucketDB(const document::BucketId& id)
-{
+DistributorStripeTestUtil::removeFromBucketDB(const document::BucketId& id) {
getBucketDatabase().remove(id);
}
void
-DistributorStripeTestUtil::addIdealNodes(const document::BucketId& id)
-{
+DistributorStripeTestUtil::addIdealNodes(const document::BucketId& id) {
// TODO STRIPE roundabout way of getting state bundle..!
addIdealNodes(*operation_context().cluster_state_bundle().getBaselineClusterState(), id);
}
void
-DistributorStripeTestUtil::insertBucketInfo(document::BucketId id,
- uint16_t node,
- uint32_t checksum,
- uint32_t count,
- uint32_t size,
- bool trusted,
- bool active)
+DistributorStripeTestUtil::insertBucketInfo(document::BucketId id, uint16_t node, uint32_t checksum,
+ uint32_t count, uint32_t size, bool trusted, bool active)
{
api::BucketInfo info(checksum, count, size);
insertBucketInfo(id, node, info, trusted, active);
}
void
-DistributorStripeTestUtil::insertBucketInfo(document::BucketId id,
- uint16_t node,
- const api::BucketInfo& info,
- bool trusted,
- bool active)
+DistributorStripeTestUtil::insertBucketInfo(document::BucketId id, uint16_t node, const api::BucketInfo& info,
+ bool trusted, bool active)
{
BucketDatabase::Entry entry = getBucketDatabase().get(id);
if (!entry.valid()) {
@@ -358,9 +324,7 @@ DistributorStripeTestUtil::insertBucketInfo(document::BucketId id,
info2.setActive();
}
BucketCopy copy(operation_context().generate_unique_timestamp(), node, info2);
-
entry->addNode(copy.setTrusted(trusted), toVector<uint16_t>(0));
-
getBucketDatabase().update(entry);
}
@@ -371,9 +335,7 @@ DistributorStripeTestUtil::dumpBucket(const document::BucketId& bid)
}
void
-DistributorStripeTestUtil::sendReply(Operation& op,
- int idx,
- api::ReturnCode::Result result)
+DistributorStripeTestUtil::sendReply(Operation& op, int idx, api::ReturnCode::Result result)
{
if (idx == -1) {
idx = _sender.commands().size() - 1;
@@ -387,20 +349,17 @@ DistributorStripeTestUtil::sendReply(Operation& op,
}
BucketDatabase::Entry
-DistributorStripeTestUtil::getBucket(const document::Bucket& bucket) const
-{
+DistributorStripeTestUtil::getBucket(const document::Bucket& bucket) const {
return getBucketDatabase(bucket.getBucketSpace()).get(bucket.getBucketId());
}
BucketDatabase::Entry
-DistributorStripeTestUtil::getBucket(const document::BucketId& bId) const
-{
+DistributorStripeTestUtil::getBucket(const document::BucketId& bId) const {
return getBucketDatabase().get(bId);
}
void
-DistributorStripeTestUtil::disableBucketActivationInConfig(bool disable)
-{
+DistributorStripeTestUtil::disableBucketActivationInConfig(bool disable) {
ConfigBuilder builder;
builder.disableBucketActivation = disable;
configure_stripe(builder);
@@ -437,14 +396,12 @@ DistributorStripeTestUtil::doc_selection_parser() const {
}
DistributorMetricSet&
-DistributorStripeTestUtil::metrics()
-{
+DistributorStripeTestUtil::metrics() {
return *_metrics;
}
bool
-DistributorStripeTestUtil::tick()
-{
+DistributorStripeTestUtil::tick() {
return _stripe->tick();
}
@@ -553,8 +510,7 @@ DistributorStripeTestUtil::getBucketSpaces() const
void
DistributorStripeTestUtil::enable_cluster_state(vespalib::stringref state)
{
- getBucketDBUpdater().simulate_cluster_state_bundle_activation(
- lib::ClusterStateBundle(lib::ClusterState(state)));
+ getBucketDBUpdater().simulate_cluster_state_bundle_activation(lib::ClusterStateBundle(lib::ClusterState(state)));
}
void
diff --git a/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp b/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
index 567e0a947da..7eb9dfe6269 100644
--- a/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
+++ b/storage/src/tests/distributor/top_level_bucket_db_updater_test.cpp
@@ -65,12 +65,9 @@ public:
close();
}
- std::shared_ptr<RequestBucketInfoReply> make_fake_bucket_reply(
- const lib::ClusterState& state,
- const RequestBucketInfoCommand& cmd,
- int storageIndex,
- uint32_t bucketCount,
- uint32_t invalidBucketCount = 0)
+ std::shared_ptr<RequestBucketInfoReply>
+ make_fake_bucket_reply(const lib::ClusterState& state, const RequestBucketInfoCommand& cmd,
+ int storageIndex, uint32_t bucketCount,uint32_t invalidBucketCount = 0)
{
auto sreply = std::make_shared<RequestBucketInfoReply>(cmd);
sreply->setAddress(storage_address(storageIndex));
@@ -84,19 +81,14 @@ public:
}
std::vector<uint16_t> nodes;
- distributor_bucket_space(bucket).getDistribution().getIdealNodes(
- lib::NodeType::STORAGE, state, bucket, nodes);
+ distributor_bucket_space(bucket).getDistribution().getIdealNodes(lib::NodeType::STORAGE, state, bucket, nodes, "uim");
for (uint32_t j = 0; j < nodes.size(); ++j) {
if (nodes[j] == storageIndex) {
if (i >= bucketCount) {
- vec.push_back(api::RequestBucketInfoReply::Entry(
- document::BucketId(16, i),
- api::BucketInfo()));
+ vec.emplace_back(document::BucketId(16, i), api::BucketInfo());
} else {
- vec.push_back(api::RequestBucketInfoReply::Entry(
- document::BucketId(16, i),
- api::BucketInfo(10,1,1)));
+ vec.emplace_back(document::BucketId(16, i), api::BucketInfo(10,1,1));
}
}
}
@@ -105,45 +97,34 @@ public:
return sreply;
}
- void fake_bucket_reply(const lib::ClusterState &state,
- const api::StorageCommand &cmd,
- uint32_t bucket_count,
- uint32_t invalid_bucket_count = 0)
+ void fake_bucket_reply(const lib::ClusterState &state, const api::StorageCommand &cmd,
+ uint32_t bucket_count, uint32_t invalid_bucket_count = 0)
{
ASSERT_EQ(cmd.getType(), MessageType::REQUESTBUCKETINFO);
const api::StorageMessageAddress& address(*cmd.getAddress());
bucket_db_updater().onRequestBucketInfoReply(
- make_fake_bucket_reply(state,
- dynamic_cast<const RequestBucketInfoCommand &>(cmd),
- address.getIndex(),
- bucket_count,
- invalid_bucket_count));
+ make_fake_bucket_reply(state, dynamic_cast<const RequestBucketInfoCommand &>(cmd),
+ address.getIndex(), bucket_count, invalid_bucket_count));
}
- void fake_bucket_reply(const lib::ClusterState &state,
- const api::StorageCommand &cmd,
- uint32_t bucket_count,
+ void fake_bucket_reply(const lib::ClusterState &state, const api::StorageCommand &cmd, uint32_t bucket_count,
const std::function<void(api::RequestBucketInfoReply&)>& reply_decorator)
{
ASSERT_EQ(cmd.getType(), MessageType::REQUESTBUCKETINFO);
const api::StorageMessageAddress& address(*cmd.getAddress());
- auto reply = make_fake_bucket_reply(state,
- dynamic_cast<const RequestBucketInfoCommand &>(cmd),
- address.getIndex(),
- bucket_count, 0);
+ auto reply = make_fake_bucket_reply(state, dynamic_cast<const RequestBucketInfoCommand &>(cmd),
+ address.getIndex(), bucket_count, 0);
reply_decorator(*reply);
bucket_db_updater().onRequestBucketInfoReply(reply);
}
- void send_fake_reply_for_single_bucket_request(
- const api::RequestBucketInfoCommand& rbi)
+ void send_fake_reply_for_single_bucket_request(const api::RequestBucketInfoCommand& rbi)
{
ASSERT_EQ(size_t(1), rbi.getBuckets().size());
const document::BucketId& bucket(rbi.getBuckets()[0]);
auto reply = std::make_shared<api::RequestBucketInfoReply>(rbi);
- reply->getBucketInfo().push_back(
- api::RequestBucketInfoReply::Entry(bucket, api::BucketInfo(20, 10, 12, 50, 60, true, true)));
+ reply->getBucketInfo().emplace_back(bucket, api::BucketInfo(20, 10, 12, 50, 60, true, true));
stripe_of_bucket(bucket).bucket_db_updater().onRequestBucketInfoReply(reply);
}
@@ -154,15 +135,11 @@ public:
}
std::vector<uint16_t> nodes;
- distributor_bucket_space(id).getDistribution().getIdealNodes(
- lib::NodeType::STORAGE, state, document::BucketId(id), nodes);
+ distributor_bucket_space(id).getDistribution().getIdealNodes(lib::NodeType::STORAGE, state, document::BucketId(id), nodes, "uim");
if (nodes.size() != entry->getNodeCount()) {
- return vespalib::make_string("Bucket Id %s has %d nodes in "
- "ideal state, but has only %d in DB",
- id.toString().c_str(),
- (int)nodes.size(),
- (int)entry->getNodeCount());
+ return vespalib::make_string("Bucket Id %s has %d nodes in ideal state, but has only %d in DB",
+ id.toString().c_str(), (int)nodes.size(), (int)entry->getNodeCount());
}
for (uint32_t i = 0; i<nodes.size(); i++) {
@@ -175,10 +152,7 @@ public:
}
if (!found) {
- return vespalib::make_string(
- "Bucket Id %s has no copy from node %d",
- id.toString().c_str(),
- nodes[i]);
+ return vespalib::make_string("Bucket Id %s has no copy from node %d", id.toString().c_str(), nodes[i]);
}
}
@@ -188,13 +162,11 @@ public:
struct OrderByIncreasingNodeIndex {
template <typename T>
bool operator()(const T& lhs, const T& rhs) {
- return (lhs->getAddress()->getIndex()
- < rhs->getAddress()->getIndex());
+ return (lhs->getAddress()->getIndex() < rhs->getAddress()->getIndex());
}
};
- void sort_sent_messages_by_index(DistributorMessageSenderStub& sender,
- size_t sortFromOffset = 0)
+ void sort_sent_messages_by_index(DistributorMessageSenderStub& sender, size_t sortFromOffset = 0)
{
std::sort(sender.commands().begin() + sortFromOffset,
sender.commands().end(),
diff --git a/storage/src/tests/distributor/top_level_distributor_test_util.cpp b/storage/src/tests/distributor/top_level_distributor_test_util.cpp
index 9677ea568e8..9859a6fb237 100644
--- a/storage/src/tests/distributor/top_level_distributor_test_util.cpp
+++ b/storage/src/tests/distributor/top_level_distributor_test_util.cpp
@@ -187,7 +187,7 @@ TopLevelDistributorTestUtil::get_ideal_str(document::BucketId id, const lib::Clu
return id.toString();
}
std::vector<uint16_t> nodes;
- _component->getDistribution()->getIdealNodes(lib::NodeType::STORAGE, state, id, nodes);
+ _component->getDistribution()->getIdealNodes(lib::NodeType::STORAGE, state, id, nodes, "uim");
std::sort(nodes.begin(), nodes.end());
std::ostringstream ost;
ost << id << ": " << dumpVector(nodes);
@@ -205,14 +205,11 @@ TopLevelDistributorTestUtil::add_ideal_nodes(const lib::ClusterState& state, con
std::vector<uint16_t> res;
assert(_component.get());
- _component->getDistribution()->getIdealNodes(lib::NodeType::STORAGE, state, id, res);
+ _component->getDistribution()->getIdealNodes(lib::NodeType::STORAGE, state, id, res, "uim");
for (uint32_t i = 0; i < res.size(); ++i) {
- if (state.getNodeState(lib::Node(lib::NodeType::STORAGE, res[i])).getState() !=
- lib::State::MAINTENANCE)
- {
- entry->addNode(BucketCopy(0, res[i], api::BucketInfo(1,1,1)),
- toVector<uint16_t>(0));
+ if (state.getNodeState(lib::Node(lib::NodeType::STORAGE, res[i])).getState() != lib::State::MAINTENANCE) {
+ entry->addNode(BucketCopy(0, res[i], api::BucketInfo(1,1,1)), toVector<uint16_t>(0));
}
}
diff --git a/storage/src/vespa/storage/bucketdb/bucketcopy.h b/storage/src/vespa/storage/bucketdb/bucketcopy.h
index e8d1db1d824..ca629a6cd8e 100644
--- a/storage/src/vespa/storage/bucketdb/bucketcopy.h
+++ b/storage/src/vespa/storage/bucketdb/bucketcopy.h
@@ -7,10 +7,10 @@ namespace storage {
class BucketCopy {
private:
- uint64_t _timestamp;
+ uint64_t _timestamp;
api::BucketInfo _info;
- uint16_t _flags;
- uint16_t _node;
+ uint16_t _flags;
+ uint16_t _node;
public:
static const int TRUSTED = 1;
@@ -18,9 +18,7 @@ public:
BucketCopy() noexcept
: _timestamp(0), _flags(0), _node(0xffff) {}
- BucketCopy(uint64_t timestamp,
- uint16_t nodeIdx,
- const api::BucketInfo& info) noexcept
+ BucketCopy(uint64_t timestamp, uint16_t nodeIdx, const api::BucketInfo& info) noexcept
: _timestamp(timestamp),
_info(info),
_flags(0),
@@ -76,16 +74,14 @@ public:
_info.setActive(setactive);
}
- bool consistentWith(const BucketCopy& other,
- bool countInvalidAsConsistent = false) const noexcept
- {
+ bool consistentWith(const BucketCopy& other) const noexcept {
// If both are valid, check checksum and doc count.
if (valid() && other.valid()) {
return (getChecksum() == other.getChecksum()
&& getDocumentCount() == other.getDocumentCount());
}
- return countInvalidAsConsistent;
+ return false;
}
void print(std::ostream&, bool verbose, const std::string& indent) const;
@@ -93,9 +89,7 @@ public:
std::string toString() const;
bool operator==(const BucketCopy& other) const noexcept {
- return
- getBucketInfo() == other.getBucketInfo() &&
- _flags == other._flags;
+ return (getBucketInfo() == other.getBucketInfo()) && (_flags == other._flags);
}
};
diff --git a/storage/src/vespa/storage/bucketdb/bucketinfo.cpp b/storage/src/vespa/storage/bucketdb/bucketinfo.cpp
index dcf49b4d022..a8c21efa793 100644
--- a/storage/src/vespa/storage/bucketdb/bucketinfo.cpp
+++ b/storage/src/vespa/storage/bucketdb/bucketinfo.cpp
@@ -9,9 +9,9 @@ namespace storage {
template class BucketInfoBase<std::vector<BucketCopy>>;
template class BucketInfoBase<vespalib::ConstArrayRef<BucketCopy>>;
-BucketInfo::BucketInfo() : BucketInfoBase() {}
+BucketInfo::BucketInfo() noexcept : BucketInfoBase() {}
-BucketInfo::BucketInfo(uint32_t lastGarbageCollection, std::vector<BucketCopy> nodes)
+BucketInfo::BucketInfo(uint32_t lastGarbageCollection, std::vector<BucketCopy> nodes) noexcept
: BucketInfoBase(lastGarbageCollection, std::move(nodes))
{}
@@ -23,7 +23,7 @@ BucketInfo::BucketInfo(BucketInfo&&) noexcept = default;
BucketInfo& BucketInfo::operator=(BucketInfo&&) noexcept = default;
void
-BucketInfo::updateTrusted() {
+BucketInfo::updateTrusted() noexcept {
if (validAndConsistent()) {
for (uint32_t i = 0; i < _nodes.size(); i++) {
_nodes[i].setTrusted();
@@ -51,7 +51,7 @@ BucketInfo::updateTrusted() {
}
void
-BucketInfo::resetTrusted() {
+BucketInfo::resetTrusted() noexcept {
for (uint32_t i = 0; i < _nodes.size(); i++) {
_nodes[i].clearTrusted();
}
@@ -63,10 +63,10 @@ namespace {
struct Sorter {
const std::vector<uint16_t>& _order;
- Sorter(const std::vector<uint16_t>& recommendedOrder) :
+ Sorter(const std::vector<uint16_t>& recommendedOrder) noexcept :
_order(recommendedOrder) {}
- bool operator() (const BucketCopy& a, const BucketCopy& b) {
+ bool operator() (const BucketCopy& a, const BucketCopy& b) noexcept {
int order_a = -1;
for (uint32_t i = 0; i < _order.size(); i++) {
if (_order[i] == a.getNode()) {
@@ -119,8 +119,7 @@ BucketInfo::addNodes(const std::vector<BucketCopy>& newCopies,
if (found) {
if (found->getTimestamp() < newCopies[i].getTimestamp()) {
- found->setBucketInfo(newCopies[i].getTimestamp(),
- newCopies[i].getBucketInfo());
+ found->setBucketInfo(newCopies[i].getTimestamp(), newCopies[i].getBucketInfo());
}
} else {
_nodes.push_back(newCopies[i]);
@@ -135,19 +134,15 @@ BucketInfo::addNodes(const std::vector<BucketCopy>& newCopies,
}
void
-BucketInfo::addNode(const BucketCopy& newCopy,
- const std::vector<uint16_t>& recommendedOrder)
+BucketInfo::addNode(const BucketCopy& newCopy, const std::vector<uint16_t>& recommendedOrder)
{
- addNodes(toVector<BucketCopy>(newCopy),
- recommendedOrder);
+ addNodes(toVector<BucketCopy>(newCopy), recommendedOrder);
}
bool
BucketInfo::removeNode(unsigned short node, TrustedUpdate update)
{
- for (std::vector<BucketCopy>::iterator iter = _nodes.begin();
- iter != _nodes.end();
- iter++) {
+ for (auto iter = _nodes.begin(); iter != _nodes.end(); iter++) {
if (iter->getNode() == node) {
_nodes.erase(iter);
if (update == TrustedUpdate::UPDATE) {
@@ -162,11 +157,9 @@ BucketInfo::removeNode(unsigned short node, TrustedUpdate update)
BucketCopy*
BucketInfo::getNodeInternal(uint16_t node)
{
- for (std::vector<BucketCopy>::iterator iter = _nodes.begin();
- iter != _nodes.end();
- iter++) {
- if (iter->getNode() == node) {
- return &*iter;
+ for (BucketCopy & copy : _nodes) {
+ if (copy.getNode() == node) {
+ return &copy;
}
}
return 0;
diff --git a/storage/src/vespa/storage/bucketdb/bucketinfo.h b/storage/src/vespa/storage/bucketdb/bucketinfo.h
index 57ebf505a50..219d0335966 100644
--- a/storage/src/vespa/storage/bucketdb/bucketinfo.h
+++ b/storage/src/vespa/storage/bucketdb/bucketinfo.h
@@ -25,15 +25,15 @@ protected:
uint32_t _lastGarbageCollection;
NodeSeq _nodes;
public:
- BucketInfoBase()
+ BucketInfoBase() noexcept
: _lastGarbageCollection(0),
_nodes()
{}
- BucketInfoBase(uint32_t lastGarbageCollection, const NodeSeq& nodes)
+ BucketInfoBase(uint32_t lastGarbageCollection, const NodeSeq& nodes) noexcept
: _lastGarbageCollection(lastGarbageCollection),
_nodes(nodes)
{}
- BucketInfoBase(uint32_t lastGarbageCollection, NodeSeq&& nodes)
+ BucketInfoBase(uint32_t lastGarbageCollection, NodeSeq&& nodes) noexcept
: _lastGarbageCollection(lastGarbageCollection),
_nodes(std::move(nodes))
{}
@@ -47,28 +47,28 @@ public:
/**
* @return Returns the last time when this bucket was "garbage collected".
*/
- uint32_t getLastGarbageCollectionTime() const { return _lastGarbageCollection; }
+ uint32_t getLastGarbageCollectionTime() const noexcept { return _lastGarbageCollection; }
/** True if the bucket contains no documents and is consistent. */
- bool emptyAndConsistent() const;
+ bool emptyAndConsistent() const noexcept;
/**
Check that all copies have complete bucket information and are
consistent with eachother.
*/
- bool validAndConsistent() const;
+ bool validAndConsistent() const noexcept;
/**
* True if the bucket contains at least one invalid copy
*/
- bool hasInvalidCopy() const;
+ bool hasInvalidCopy() const noexcept;
/**
* Returns the number of trusted nodes this entry has.
*/
- uint16_t getTrustedCount() const;
+ uint16_t getTrustedCount() const noexcept;
- bool hasTrusted() const {
+ bool hasTrusted() const noexcept {
return getTrustedCount() != 0;
}
@@ -78,14 +78,14 @@ public:
* @param countInCompleteAsInconsistent If false, nodes that are incomplete
* are always counted as consistent with complete nodes.
*/
- bool consistentNodes(bool countInvalidAsConsistent = false) const;
+ bool consistentNodes() const noexcept;
void print(std::ostream&, bool verbose, const std::string& indent) const;
/**
* Returns the bucket copy struct for the given node, null if nonexisting
*/
- const BucketCopy* getNode(uint16_t node) const;
+ const BucketCopy* getNode(uint16_t node) const noexcept;
/**
* Returns the number of nodes this entry has.
@@ -95,7 +95,7 @@ public:
/**
* Returns a list of the nodes this entry has.
*/
- std::vector<uint16_t> getNodes() const;
+ std::vector<uint16_t> getNodes() const noexcept;
/**
Returns a reference to the node with the given index in the node
@@ -117,14 +117,14 @@ public:
std::string toString() const;
- uint32_t getHighestDocumentCount() const;
- uint32_t getHighestTotalDocumentSize() const;
- uint32_t getHighestMetaCount() const;
- uint32_t getHighestUsedFileSize() const;
+ uint32_t getHighestDocumentCount() const noexcept;
+ uint32_t getHighestTotalDocumentSize() const noexcept;
+ uint32_t getHighestMetaCount() const noexcept;
+ uint32_t getHighestUsedFileSize() const noexcept;
- bool hasRecentlyCreatedEmptyCopy() const;
+ bool hasRecentlyCreatedEmptyCopy() const noexcept;
- bool operator==(const BucketInfoBase& other) const;
+ bool operator==(const BucketInfoBase& other) const noexcept;
};
template <typename NodeSeq>
@@ -140,8 +140,8 @@ public:
class BucketInfo : public BucketInfoBase<std::vector<BucketCopy>> {
public:
- BucketInfo();
- BucketInfo(uint32_t lastGarbageCollection, std::vector<BucketCopy> nodes);
+ BucketInfo() noexcept;
+ BucketInfo(uint32_t lastGarbageCollection, std::vector<BucketCopy> nodes) noexcept;
~BucketInfo();
BucketInfo(const BucketInfo&);
@@ -152,20 +152,20 @@ public:
/**
* Sets the last time the bucket was "garbage collected".
*/
- void setLastGarbageCollectionTime(uint32_t timestamp) {
+ void setLastGarbageCollectionTime(uint32_t timestamp) noexcept {
_lastGarbageCollection = timestamp;
}
/**
Update trusted flags if bucket is now complete and consistent.
*/
- void updateTrusted();
+ void updateTrusted() noexcept;
/**
Removes any historical information on trustedness, and sets the bucket copies to
trusted if they are now complete and consistent.
*/
- void resetTrusted();
+ void resetTrusted() noexcept;
/**
Adds the given node.
@@ -184,8 +184,7 @@ public:
/**
Simplified API for the common case of inserting one node. See addNodes().
*/
- void addNode(const BucketCopy& newCopy,
- const std::vector<uint16_t>& recommendedOrder);
+ void addNode(const BucketCopy& newCopy, const std::vector<uint16_t>& recommendedOrder);
/**
Updates bucket information for a node. Does nothing if the node
diff --git a/storage/src/vespa/storage/bucketdb/bucketinfo.hpp b/storage/src/vespa/storage/bucketdb/bucketinfo.hpp
index b7e8c5925c5..ce7adc8af67 100644
--- a/storage/src/vespa/storage/bucketdb/bucketinfo.hpp
+++ b/storage/src/vespa/storage/bucketdb/bucketinfo.hpp
@@ -9,16 +9,18 @@
namespace storage {
template <typename NodeSeq>
-std::string BucketInfoBase<NodeSeq>::toString() const {
+std::string
+BucketInfoBase<NodeSeq>::toString() const {
std::ostringstream ost;
print(ost, true, "");
return ost.str();
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::emptyAndConsistent() const {
- for (uint32_t i = 0; i < _nodes.size(); i++) {
- if (!_nodes[i].empty()) {
+bool
+BucketInfoBase<NodeSeq>::emptyAndConsistent() const noexcept {
+ for (const auto & n : _nodes) {
+ if (!n.empty()) {
return false;
}
}
@@ -26,9 +28,10 @@ bool BucketInfoBase<NodeSeq>::emptyAndConsistent() const {
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::validAndConsistent() const {
- for (uint32_t i = 0; i < _nodes.size(); i++) {
- if (!_nodes[i].valid()) {
+bool
+BucketInfoBase<NodeSeq>::validAndConsistent() const noexcept {
+ for (const auto & n : _nodes) {
+ if (!n.valid()) {
return false;
}
}
@@ -36,9 +39,10 @@ bool BucketInfoBase<NodeSeq>::validAndConsistent() const {
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::hasInvalidCopy() const {
- for (uint32_t i = 0; i < _nodes.size(); i++) {
- if (!_nodes[i].valid()) {
+bool
+BucketInfoBase<NodeSeq>::hasInvalidCopy() const noexcept {
+ for (const auto & n : _nodes){
+ if (!n.valid()) {
return true;
}
}
@@ -46,10 +50,11 @@ bool BucketInfoBase<NodeSeq>::hasInvalidCopy() const {
}
template <typename NodeSeq>
-uint16_t BucketInfoBase<NodeSeq>::getTrustedCount() const {
+uint16_t
+BucketInfoBase<NodeSeq>::getTrustedCount() const noexcept {
uint32_t trustedCount = 0;
- for (uint32_t i = 0; i < _nodes.size(); i++) {
- if (_nodes[i].trusted()) {
+ for (const auto & n : _nodes) {
+ if (n.trusted()) {
trustedCount++;
}
}
@@ -57,11 +62,11 @@ uint16_t BucketInfoBase<NodeSeq>::getTrustedCount() const {
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::consistentNodes(bool countInvalidAsConsistent) const {
+bool
+BucketInfoBase<NodeSeq>::consistentNodes() const noexcept {
int compareIndex = 0;
for (uint32_t i = 1; i < _nodes.size(); i++) {
- if (!_nodes[i].consistentWith(_nodes[compareIndex],
- countInvalidAsConsistent)) return false;
+ if (!_nodes[i].consistentWith(_nodes[compareIndex])) return false;
}
return true;
}
@@ -90,14 +95,16 @@ struct ReplicaMetadata {
};
};
-constexpr bool is_majority(size_t n, size_t m) {
+constexpr bool
+is_majority(size_t n, size_t m) noexcept {
return (n >= (m / 2) + 1);
}
}
template <typename NodeSeq>
-api::BucketInfo BucketInfoBase<NodeSeq>::majority_consistent_bucket_info() const noexcept {
+api::BucketInfo
+BucketInfoBase<NodeSeq>::majority_consistent_bucket_info() const noexcept {
if (_nodes.size() < 3) {
return {};
}
@@ -116,7 +123,8 @@ api::BucketInfo BucketInfoBase<NodeSeq>::majority_consistent_bucket_info() const
}
template <typename NodeSeq>
-void BucketInfoBase<NodeSeq>::print(std::ostream& out, bool verbose, const std::string& indent) const {
+void
+BucketInfoBase<NodeSeq>::print(std::ostream& out, bool verbose, const std::string& indent) const {
if (_nodes.size() == 0) {
out << "no nodes";
}
@@ -129,7 +137,8 @@ void BucketInfoBase<NodeSeq>::print(std::ostream& out, bool verbose, const std::
}
template <typename NodeSeq>
-const BucketCopy* BucketInfoBase<NodeSeq>::getNode(uint16_t node) const {
+const BucketCopy*
+BucketInfoBase<NodeSeq>::getNode(uint16_t node) const noexcept {
for (const auto& n : _nodes) {
if (n.getNode() == node) {
return &n;
@@ -139,54 +148,61 @@ const BucketCopy* BucketInfoBase<NodeSeq>::getNode(uint16_t node) const {
}
template <typename NodeSeq>
-std::vector<uint16_t> BucketInfoBase<NodeSeq>::getNodes() const {
+std::vector<uint16_t>
+BucketInfoBase<NodeSeq>::getNodes() const noexcept {
std::vector<uint16_t> result;
- for (uint32_t i = 0; i < _nodes.size(); i++) {
- result.emplace_back(_nodes[i].getNode());
+ result.reserve(_nodes.size());
+ for (const auto & n : _nodes) {
+ result.emplace_back(n.getNode());
}
return result;
}
template <typename NodeSeq>
-uint32_t BucketInfoBase<NodeSeq>::getHighestDocumentCount() const {
+uint32_t
+BucketInfoBase<NodeSeq>::getHighestDocumentCount() const noexcept {
uint32_t highest = 0;
- for (uint32_t i = 0; i < _nodes.size(); ++i) {
- highest = std::max(highest, _nodes[i].getDocumentCount());
+ for (const auto & n : _nodes) {
+ highest = std::max(highest, n.getDocumentCount());
}
return highest;
}
template <typename NodeSeq>
-uint32_t BucketInfoBase<NodeSeq>::getHighestTotalDocumentSize() const {
+uint32_t
+BucketInfoBase<NodeSeq>::getHighestTotalDocumentSize() const noexcept {
uint32_t highest = 0;
- for (uint32_t i = 0; i < _nodes.size(); ++i) {
- highest = std::max(highest, _nodes[i].getTotalDocumentSize());
+ for (const auto & n : _nodes) {
+ highest = std::max(highest, n.getTotalDocumentSize());
}
return highest;
}
template <typename NodeSeq>
-uint32_t BucketInfoBase<NodeSeq>::getHighestMetaCount() const {
+uint32_t
+BucketInfoBase<NodeSeq>::getHighestMetaCount() const noexcept {
uint32_t highest = 0;
- for (uint32_t i = 0; i < _nodes.size(); ++i) {
- highest = std::max(highest, _nodes[i].getMetaCount());
+ for (const auto & n : _nodes) {
+ highest = std::max(highest, n.getMetaCount());
}
return highest;
}
template <typename NodeSeq>
-uint32_t BucketInfoBase<NodeSeq>::getHighestUsedFileSize() const {
+uint32_t
+BucketInfoBase<NodeSeq>::getHighestUsedFileSize() const noexcept {
uint32_t highest = 0;
- for (uint32_t i = 0; i < _nodes.size(); ++i) {
- highest = std::max(highest, _nodes[i].getUsedFileSize());
+ for (const auto & n : _nodes) {
+ highest = std::max(highest, n.getUsedFileSize());
}
return highest;
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::hasRecentlyCreatedEmptyCopy() const {
- for (uint32_t i = 0; i < _nodes.size(); ++i) {
- if (_nodes[i].wasRecentlyCreated()) {
+bool
+BucketInfoBase<NodeSeq>::hasRecentlyCreatedEmptyCopy() const noexcept {
+ for (const auto & n : _nodes) {
+ if (n.wasRecentlyCreated()) {
return true;
}
}
@@ -194,7 +210,8 @@ bool BucketInfoBase<NodeSeq>::hasRecentlyCreatedEmptyCopy() const {
}
template <typename NodeSeq>
-bool BucketInfoBase<NodeSeq>::operator==(const BucketInfoBase<NodeSeq>& other) const {
+bool
+BucketInfoBase<NodeSeq>::operator==(const BucketInfoBase<NodeSeq>& other) const noexcept {
if (_nodes.size() != other._nodes.size()) {
return false;
}
@@ -210,6 +227,6 @@ bool BucketInfoBase<NodeSeq>::operator==(const BucketInfoBase<NodeSeq>& other) c
}
return true;
-};
+}
}
diff --git a/storage/src/vespa/storage/distributor/activecopy.cpp b/storage/src/vespa/storage/distributor/activecopy.cpp
index c46e9868cc8..ea194e1be21 100644
--- a/storage/src/vespa/storage/distributor/activecopy.cpp
+++ b/storage/src/vespa/storage/distributor/activecopy.cpp
@@ -91,66 +91,62 @@ operator<<(std::ostream& out, const ActiveCopy & e) {
namespace {
- struct ActiveStateOrder {
- bool operator()(const ActiveCopy & e1, const ActiveCopy & e2) {
- if (e1._ready != e2._ready) {
- return e1._ready;
- }
- if (e1._doc_count != e2._doc_count) {
- return e1._doc_count > e2._doc_count;
- }
- if (e1._ideal != e2._ideal) {
- return e1._ideal < e2._ideal;
- }
- if (e1._active != e2._active) {
- return e1._active;
- }
- return e1._nodeIndex < e2._nodeIndex;
+struct ActiveStateOrder {
+ bool operator()(const ActiveCopy & e1, const ActiveCopy & e2) noexcept {
+ if (e1._ready != e2._ready) {
+ return e1._ready;
}
- };
-
- std::vector<uint16_t>
- buildValidNodeIndexList(BucketDatabase::Entry& e) {
- std::vector<uint16_t> result;
- result.reserve(e->getNodeCount());
- for (uint32_t i=0, n=e->getNodeCount(); i < n; ++i) {
- const BucketCopy& cp = e->getNodeRef(i);
- if (!cp.valid()) {
- continue;
- }
- result.push_back(cp.getNode());
+ if (e1._doc_count != e2._doc_count) {
+ return e1._doc_count > e2._doc_count;
+ }
+ if (e1._ideal != e2._ideal) {
+ return e1._ideal < e2._ideal;
}
- return result;
+ if (e1._active != e2._active) {
+ return e1._active;
+ }
+ return e1._nodeIndex < e2._nodeIndex;
}
-
- std::vector<ActiveCopy>
- buildNodeList(BucketDatabase::Entry& e,
- const std::vector<uint16_t>& nodeIndexes,
- const std::vector<uint16_t>& idealState)
- {
- std::vector<ActiveCopy> result;
- result.reserve(nodeIndexes.size());
- for (uint16_t nodeIndex : nodeIndexes) {
- result.emplace_back(nodeIndex, e, idealState);
+};
+
+std::vector<uint16_t>
+buildValidNodeIndexList(BucketDatabase::Entry& e) {
+ std::vector<uint16_t> result;
+ result.reserve(e->getNodeCount());
+ for (uint32_t i=0, n=e->getNodeCount(); i < n; ++i) {
+ const BucketCopy& cp = e->getNodeRef(i);
+ if (!cp.valid()) {
+ continue;
}
- return result;
+ result.push_back(cp.getNode());
}
+ return result;
+}
+
+std::vector<ActiveCopy>
+buildNodeList(BucketDatabase::Entry& e, const std::vector<uint16_t>& nodeIndexes, const std::vector<uint16_t>& idealState)
+{
+ std::vector<ActiveCopy> result;
+ result.reserve(nodeIndexes.size());
+ for (uint16_t nodeIndex : nodeIndexes) {
+ result.emplace_back(nodeIndex, e, idealState);
+ }
+ return result;
+}
+
}
ActiveList
-ActiveCopy::calculate(const std::vector<uint16_t>& idealState,
- const lib::Distribution& distribution,
- BucketDatabase::Entry& e,
- uint32_t max_activation_inhibited_out_of_sync_groups)
+ActiveCopy::calculate(const std::vector<uint16_t>& idealState, const lib::Distribution& distribution,
+ BucketDatabase::Entry& e, uint32_t max_activation_inhibited_out_of_sync_groups)
{
std::vector<uint16_t> validNodesWithCopy = buildValidNodeIndexList(e);
if (validNodesWithCopy.empty()) {
return ActiveList();
}
- using IndexList = std::vector<uint16_t>;
- std::vector<IndexList> groups;
+ std::vector<lib::Distribution::IndexList> groups;
if (distribution.activePerGroup()) {
- groups = distribution.splitNodesIntoLeafGroups(std::move(validNodesWithCopy));
+ groups = distribution.splitNodesIntoLeafGroups(validNodesWithCopy);
} else {
groups.push_back(std::move(validNodesWithCopy));
}
diff --git a/storage/src/vespa/storage/distributor/idealstatemanager.cpp b/storage/src/vespa/storage/distributor/idealstatemanager.cpp
index cad141e76ed..bc928ca3d41 100644
--- a/storage/src/vespa/storage/distributor/idealstatemanager.cpp
+++ b/storage/src/vespa/storage/distributor/idealstatemanager.cpp
@@ -10,10 +10,9 @@
#include <vespa/storageapi/message/persistence.h>
#include <vespa/document/bucket/fixed_bucket_spaces.h>
#include <vespa/vespalib/util/assert.h>
-#include <vespa/vespalib/stllike/hash_map.hpp>
#include <vespa/log/log.h>
-LOG_SETUP(".distributor.operation.queue");
+LOG_SETUP(".distributor.idealstatemanager");
using document::BucketSpace;
using storage::lib::Node;
@@ -21,10 +20,9 @@ using storage::lib::NodeType;
namespace storage::distributor {
-IdealStateManager::IdealStateManager(
- const DistributorNodeContext& node_ctx,
- DistributorStripeOperationContext& op_ctx,
- IdealStateMetricSet& metrics)
+IdealStateManager::IdealStateManager(const DistributorNodeContext& node_ctx,
+ DistributorStripeOperationContext& op_ctx,
+ IdealStateMetricSet& metrics)
: _metrics(metrics),
_stateCheckers(),
_splitBucketStateChecker(nullptr),
@@ -56,9 +54,7 @@ IdealStateManager::fillParentAndChildBuckets(StateChecker::Context& c)
{
c.db.getAll(c.getBucketId(), c.entries);
if (c.entries.empty()) {
- LOG(spam,
- "Did not find bucket %s in bucket database",
- c.bucket.toString().c_str());
+ LOG(spam, "Did not find bucket %s in bucket database", c.bucket.toString().c_str());
}
}
void
@@ -85,8 +81,7 @@ namespace {
* overwriting if already explicitly set.
*/
bool
-canOverwriteResult(const StateChecker::Result& existing,
- const StateChecker::Result& candidate)
+canOverwriteResult(const StateChecker::Result& existing, const StateChecker::Result& candidate)
{
return (!existing.getPriority().requiresMaintenance()
&& candidate.getPriority().requiresMaintenance());
@@ -101,9 +96,7 @@ IdealStateManager::runStateCheckers(StateChecker::Context& c) const
// We go through _all_ active state checkers so that statistics can be
// collected across all checkers, not just the ones that are highest pri.
for (const auto & checker : _stateCheckers) {
- if (!operation_context().distributor_config().stateCheckerIsActive(
- checker->getName()))
- {
+ if (!operation_context().distributor_config().stateCheckerIsActive(checker->getName())) {
LOG(spam, "Skipping state checker %s", checker->getName());
continue;
}
@@ -116,7 +109,8 @@ IdealStateManager::runStateCheckers(StateChecker::Context& c) const
return highestPri;
}
-void IdealStateManager::verify_only_live_nodes_in_context(const StateChecker::Context& c) const {
+void
+IdealStateManager::verify_only_live_nodes_in_context(const StateChecker::Context& c) const {
if (_has_logged_phantom_replica_warning) {
return;
}
@@ -125,11 +119,8 @@ void IdealStateManager::verify_only_live_nodes_in_context(const StateChecker::Co
const auto& state = c.systemState.getNodeState(lib::Node(lib::NodeType::STORAGE, index));
// Only nodes in Up, Initializing or Retired should ever be present in the DB.
if (!state.getState().oneOf("uir")) {
- LOG(error, "%s in bucket DB is on node %u, which is in unavailable state %s. "
- "Current cluster state is '%s'",
- c.entry.getBucketId().toString().c_str(),
- index,
- state.getState().toString().c_str(),
+ LOG(error, "%s in bucket DB is on node %u, which is in unavailable state %s. Current cluster state is '%s'",
+ c.entry.getBucketId().toString().c_str(), index, state.getState().toString().c_str(),
c.systemState.toString().c_str());
ASSERT_ONCE_OR_LOG(false, "Bucket DB contains replicas on unavailable node", 10000);
_has_logged_phantom_replica_warning = true;
@@ -138,9 +129,7 @@ void IdealStateManager::verify_only_live_nodes_in_context(const StateChecker::Co
}
StateChecker::Result
-IdealStateManager::generateHighestPriority(
- const document::Bucket& bucket,
- NodeMaintenanceStatsTracker& statsTracker) const
+IdealStateManager::generateHighestPriority(const document::Bucket& bucket, NodeMaintenanceStatsTracker& statsTracker) const
{
auto& distributorBucketSpace = _op_ctx.bucket_space_repo().get(bucket.getBucketSpace());
StateChecker::Context c(node_context(), operation_context(), distributorBucketSpace, statsTracker, bucket);
@@ -159,9 +148,7 @@ IdealStateManager::generateHighestPriority(
}
MaintenancePriorityAndType
-IdealStateManager::prioritize(
- const document::Bucket& bucket,
- NodeMaintenanceStatsTracker& statsTracker) const
+IdealStateManager::prioritize(const document::Bucket& bucket, NodeMaintenanceStatsTracker& statsTracker) const
{
StateChecker::Result generated(generateHighestPriority(bucket, statsTracker));
MaintenancePriority priority(generated.getPriority());
@@ -172,8 +159,7 @@ IdealStateManager::prioritize(
}
IdealStateOperation::SP
-IdealStateManager::generateInterceptingSplit(BucketSpace bucketSpace,
- const BucketDatabase::Entry& e,
+IdealStateManager::generateInterceptingSplit(BucketSpace bucketSpace, const BucketDatabase::Entry& e,
api::StorageMessage::Priority pri)
{
NodeMaintenanceStatsTracker statsTracker;
@@ -199,18 +185,15 @@ MaintenanceOperation::SP
IdealStateManager::generate(const document::Bucket& bucket) const
{
NodeMaintenanceStatsTracker statsTracker;
- IdealStateOperation::SP op(
- generateHighestPriority(bucket, statsTracker).createOperation());
+ IdealStateOperation::SP op(generateHighestPriority(bucket, statsTracker).createOperation());
if (op.get()) {
- op->setIdealStateManager(
- const_cast<IdealStateManager*>(this));
+ op->setIdealStateManager(const_cast<IdealStateManager*>(this));
}
return op;
}
std::vector<MaintenanceOperation::SP>
-IdealStateManager::generateAll(const document::Bucket &bucket,
- NodeMaintenanceStatsTracker& statsTracker) const
+IdealStateManager::generateAll(const document::Bucket &bucket, NodeMaintenanceStatsTracker& statsTracker) const
{
auto& distributorBucketSpace = _op_ctx.bucket_space_repo().get(bucket.getBucketSpace());
StateChecker::Context c(node_context(), operation_context(), distributorBucketSpace, statsTracker, bucket);
@@ -234,15 +217,11 @@ IdealStateManager::generateAll(const document::Bucket &bucket,
}
void
-IdealStateManager::getBucketStatus(
- BucketSpace bucketSpace,
- const BucketDatabase::ConstEntryRef& entry,
- NodeMaintenanceStatsTracker& statsTracker,
- std::ostream& out) const
+IdealStateManager::getBucketStatus(BucketSpace bucketSpace, const BucketDatabase::ConstEntryRef& entry,
+ NodeMaintenanceStatsTracker& statsTracker, std::ostream& out) const
{
document::Bucket bucket(bucketSpace, entry.getBucketId());
- std::vector<MaintenanceOperation::SP> operations(
- generateAll(bucket, statsTracker));
+ std::vector<MaintenanceOperation::SP> operations(generateAll(bucket, statsTracker));
if (operations.empty()) {
out << entry.getBucketId() << " : ";
} else {
@@ -261,13 +240,15 @@ IdealStateManager::getBucketStatus(
out << "[" << entry->toString() << "]<br>\n";
}
-void IdealStateManager::dump_bucket_space_db_status(document::BucketSpace bucket_space, std::ostream& out) const {
+void
+IdealStateManager::dump_bucket_space_db_status(document::BucketSpace bucket_space, std::ostream& out) const {
StatusBucketVisitor proc(*this, bucket_space, out);
auto& distributorBucketSpace = _op_ctx.bucket_space_repo().get(bucket_space);
distributorBucketSpace.getBucketDatabase().for_each_upper_bound(proc);
}
-void IdealStateManager::getBucketStatus(std::ostream& out) const {
+void
+IdealStateManager::getBucketStatus(std::ostream& out) const {
LOG(debug, "Dumping bucket database valid at cluster state version %u",
operation_context().cluster_state_bundle().getVersion());
diff --git a/storage/src/vespa/storage/distributor/idealstatemanager.h b/storage/src/vespa/storage/distributor/idealstatemanager.h
index 0c9e3ffa1c6..39a662e4a81 100644
--- a/storage/src/vespa/storage/distributor/idealstatemanager.h
+++ b/storage/src/vespa/storage/distributor/idealstatemanager.h
@@ -49,18 +49,14 @@ public:
MaintenanceOperation::SP generate(const document::Bucket& bucket) const override;
// MaintenanceOperationGenerator
- std::vector<MaintenanceOperation::SP> generateAll(
- const document::Bucket& bucket,
- NodeMaintenanceStatsTracker& statsTracker) const override;
+ std::vector<MaintenanceOperation::SP> generateAll(const document::Bucket& bucket, NodeMaintenanceStatsTracker& statsTracker) const override;
/**
* If the given bucket is too large, generate a split operation for it,
* with higher priority than the given one.
*/
- IdealStateOperation::SP generateInterceptingSplit(
- document::BucketSpace bucketSpace,
- const BucketDatabase::Entry& e,
- api::StorageMessage::Priority pri);
+ IdealStateOperation::SP generateInterceptingSplit(document::BucketSpace bucketSpace, const BucketDatabase::Entry& e,
+ api::StorageMessage::Priority pri);
IdealStateMetricSet& getMetrics() noexcept { return _metrics; }
@@ -78,9 +74,7 @@ private:
void verify_only_live_nodes_in_context(const StateChecker::Context& c) const;
static void fillParentAndChildBuckets(StateChecker::Context& c);
static void fillSiblingBucket(StateChecker::Context& c);
- StateChecker::Result generateHighestPriority(
- const document::Bucket& bucket,
- NodeMaintenanceStatsTracker& statsTracker) const;
+ StateChecker::Result generateHighestPriority(const document::Bucket& bucket, NodeMaintenanceStatsTracker& statsTracker) const;
StateChecker::Result runStateCheckers(StateChecker::Context& c) const;
static BucketDatabase::Entry* getEntryForPrimaryBucket(StateChecker::Context& c);
diff --git a/storage/src/vespa/storage/storageutil/distributorstatecache.h b/storage/src/vespa/storage/storageutil/distributorstatecache.h
index 8c4d07e39bf..0652a980e3a 100644
--- a/storage/src/vespa/storage/storageutil/distributorstatecache.h
+++ b/storage/src/vespa/storage/storageutil/distributorstatecache.h
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+
#include <vespa/vdslib/state/clusterstate.h>
#include <vespa/vdslib/distribution/distribution.h>
@@ -9,9 +10,7 @@ namespace storage {
class DistributorStateCache
{
public:
- DistributorStateCache(
- const lib::Distribution& distr,
- const lib::ClusterState& state)
+ DistributorStateCache(const lib::Distribution& distr, const lib::ClusterState& state)
: _distribution(distr),
_state(state),
_distrBitMask(0xffffffffffffffffull),
@@ -22,8 +21,7 @@ public:
_distrBitMask >>= (64 - state.getDistributionBitCount());
}
- uint16_t getOwner(const document::BucketId& bid,
- const char* upStates = "ui")
+ uint16_t getOwner(const document::BucketId& bid, const char* upStates = "ui")
{
uint64_t distributionBits = bid.getRawId() & _distrBitMask;
diff --git a/storage/src/vespa/storage/tools/getidealstate.cpp b/storage/src/vespa/storage/tools/getidealstate.cpp
index 8b120924aaa..9e80517f4f7 100644
--- a/storage/src/vespa/storage/tools/getidealstate.cpp
+++ b/storage/src/vespa/storage/tools/getidealstate.cpp
@@ -64,18 +64,13 @@ Options::Options(int argc, const char* const* argv)
Options::~Options() {}
-void processBucket(const lib::Distribution& distribution,
- const lib::ClusterState& clusterState,
- const std::string& upStates,
- const document::BucketId& bucket)
+void processBucket(const lib::Distribution& distribution, const lib::ClusterState& clusterState,
+ const std::string& upStates, const document::BucketId& bucket)
{
std::ostringstream ost;
- std::vector<uint16_t> storageNodes(distribution.getIdealStorageNodes(
- clusterState, bucket, upStates.c_str()));
- uint16_t distributorNode(distribution.getIdealDistributorNode(
- clusterState, bucket, upStates.c_str()));
- ost << bucket << " distributor: " << distributorNode
- << ", storage:";
+ std::vector<uint16_t> storageNodes(distribution.getIdealStorageNodes(clusterState, bucket, upStates.c_str()));
+ uint16_t distributorNode(distribution.getIdealDistributorNode(clusterState, bucket, upStates.c_str()));
+ ost << bucket << " distributor: " << distributorNode << ", storage:";
for (uint32_t i=0; i<storageNodes.size(); ++i) {
ost << " " << storageNodes[i];
}
diff --git a/vdslib/src/tests/distribution/distributiontest.cpp b/vdslib/src/tests/distribution/distributiontest.cpp
index b5c756aece9..33a6d47b719 100644
--- a/vdslib/src/tests/distribution/distributiontest.cpp
+++ b/vdslib/src/tests/distribution/distributiontest.cpp
@@ -53,9 +53,7 @@ TEST(DistributionTest, test_verify_java_distributions)
long maxBucket = 1;
long mask = 0;
- for (uint32_t distributionBits = 0; distributionBits <= 32;
- ++distributionBits)
- {
+ for (uint32_t distributionBits = 0; distributionBits <= 32; ++distributionBits) {
state.setDistributionBitCount(distributionBits);
RandomGen randomizer(distributionBits);
for (uint32_t bucketIndex = 0; bucketIndex < 64; ++bucketIndex) {
@@ -66,11 +64,8 @@ TEST(DistributionTest, test_verify_java_distributions)
bucketId = randomizer.nextUint64();
}
document::BucketId bucket(distributionBits, bucketId);
- for (uint32_t redundancy = 1;
- redundancy <= distr.getRedundancy(); ++redundancy)
- {
- int distributorIndex = distr.getIdealDistributorNode(
- state, bucket, "uim");
+ for (uint32_t redundancy = 1; redundancy <= distr.getRedundancy(); ++redundancy) {
+ int distributorIndex = distr.getIdealDistributorNode(state, bucket, "uim");
of << distributionBits << " " << (bucketId & mask)
<< " " << redundancy << " " << distributorIndex << "\n";
}
@@ -102,22 +97,16 @@ struct ExpectedResult {
};
void
-verifyJavaDistribution(const vespalib::string& name,
- const ClusterState& state,
- const Distribution& distribution,
- const NodeType& nodeType,
- uint16_t redundancy,
- uint16_t nodeCount,
- vespalib::stringref upStates,
- const std::vector<ExpectedResult> results)
+verifyJavaDistribution(const vespalib::string& name, const ClusterState& state, const Distribution& distribution,
+ const NodeType& nodeType, uint16_t redundancy, uint16_t nodeCount,
+ vespalib::stringref upStates, const std::vector<ExpectedResult> results)
{
(void) nodeCount;
for (uint32_t i=0, n=results.size(); i<n; ++i) {
std::string testId = name + " " + results[i].bucket.toString();
try {
std::vector<uint16_t> nvect;
- distribution.getIdealNodes(nodeType, state, results[i].bucket,
- nvect, upStates.data(), redundancy);
+ distribution.getIdealNodes(nodeType, state, results[i].bucket, nvect, upStates.data(), redundancy);
IdealNodeList nodes;
for (uint32_t j=0, m=nvect.size(); j<m; ++j) {
nodes.push_back(Node(nodeType, nvect[j]));
@@ -155,8 +144,7 @@ auto readFile(const std::string & filename) {
TEST(DistributionTest, test_verify_java_distributions_2)
{
- vespalib::DirectoryList files(
- vespalib::listDirectory("distribution/testdata"));
+ vespalib::DirectoryList files(vespalib::listDirectory("distribution/testdata"));
for (uint32_t i=0, n=files.size(); i<n; ++i) {
size_t pos = files[i].find(".java.results");
if (pos == vespalib::string::npos || pos + 13 != files[i].size()) {
@@ -189,8 +177,7 @@ TEST(DistributionTest, test_verify_java_distributions_2)
ClusterState cs(c["cluster-state"].asString().make_string());
std::string distConfig(c["distribution"].asString().make_string());
Distribution d(distConfig);
- const NodeType& nt(
- NodeType::get(c["node-type"].asString().make_string()));
+ const NodeType& nt(NodeType::get(c["node-type"].asString().make_string()));
uint32_t redundancy(c["redundancy"].asLong());
uint32_t nodeCount(c["node-count"].asLong());
vespalib::string upStates(c["up-states"].asString().make_string());
@@ -209,8 +196,7 @@ TEST(DistributionTest, test_verify_java_distributions_2)
}
results.push_back(result);
}
- verifyJavaDistribution(name, cs, d, nt, redundancy, nodeCount,
- upStates, results);
+ verifyJavaDistribution(name, cs, d, nt, redundancy, nodeCount, upStates, results);
//std::cerr << name << ": Verified " << results.size() << " tests.\n";
}
}
@@ -223,8 +209,7 @@ TEST(DistributionTest, test_unchanged_distribution)
std::ifstream in("distribution/testdata/41-distributordistribution");
for (unsigned i = 0; i < 64_Ki; i++) {
- uint16_t node = distr.getIdealDistributorNode(
- state, document::BucketId(16, i), "u");
+ uint16_t node = distr.getIdealDistributorNode(state, document::BucketId(16, i), "u");
char buf[100];
in.getline(buf, 100);
@@ -272,9 +257,7 @@ struct MyTest {
document::BucketId bucket(16, i);
std::vector<uint16_t> nodes;
ClusterState clusterState(_state);
- _distribution->getIdealNodes(
- *_nodeType, clusterState, bucket, nodes,
- _upStates, _redundancy);
+ _distribution->getIdealNodes(*_nodeType, clusterState, bucket, nodes, _upStates, _redundancy);
for (uint32_t j=0; j<nodes.size(); ++j) {
++result[nodes[j]];
}
@@ -293,8 +276,7 @@ MyTest::MyTest()
{ }
MyTest::~MyTest() = default;
-std::vector<uint16_t> createNodeCountList(const std::string& source,
- std::vector<uint16_t>& vals) {
+std::vector<uint16_t> createNodeCountList(const std::string& source, std::vector<uint16_t>& vals) {
std::vector<uint16_t> result(vals.size(), 0);
vespalib::StringTokenizer st(source, " ");
for (uint32_t i=0; i<st.size(); ++i) {
@@ -375,15 +357,9 @@ TEST(DistributionTest, testHighSplitBit)
document::BucketId bid1 = document::BucketId(bits, base);
document::BucketId bid2 = document::BucketId(bits, base);
- std::vector<uint16_t> nodes1 =
- distr.getIdealStorageNodes(state,
- bid1,
- "u");
+ std::vector<uint16_t> nodes1 = distr.getIdealStorageNodes(state, bid1, "u");
- std::vector<uint16_t> nodes2 =
- distr.getIdealStorageNodes(state,
- bid2,
- "u");
+ std::vector<uint16_t> nodes2 = distr.getIdealStorageNodes(state, bid2, "u");
ost1 << bid1 << " vs. " << bid2 << ": ";
ost2 << bid1 << " vs. " << bid2 << ": ";
@@ -424,16 +400,14 @@ TEST(DistributionTest, test_distribution)
s1 << "storage:" << n << std::endl;
ClusterState systemState(s1.str());
- Distribution distr(
- Distribution::getDefaultDistributionConfig(3, n));
+ Distribution distr(Distribution::getDefaultDistributionConfig(3, n));
std::vector<std::pair<uint64_t, std::vector<uint16_t> > > _distribution(b);
std::vector<int> _nodeCount(n, 0);
for (int i = 0; i < b; i++) {
_distribution[i].first = i;
- _distribution[i].second = distr.getIdealStorageNodes(
- systemState, document::BucketId(26, i));
+ _distribution[i].second = distr.getIdealStorageNodes(systemState, document::BucketId(26, i));
sort(_distribution[i].second.begin(), _distribution[i].second.end());
auto unique_nodes = std::distance(_distribution[i].second.begin(), unique(_distribution[i].second.begin(), _distribution[i].second.end()));
_distribution[i].second.resize(unique_nodes);
@@ -469,9 +443,7 @@ TEST(DistributionTest, test_move)
{
ClusterState systemState("storage:3");
document::BucketId bucket(16, 0x8b4f67ae);
-
Distribution distr(Distribution::getDefaultDistributionConfig(2, 3));
-
res = distr.getIdealStorageNodes(systemState, bucket);
EXPECT_EQ(size_t(2), res.size());
}
@@ -479,11 +451,8 @@ TEST(DistributionTest, test_move)
std::vector<uint16_t> res2;
{
ClusterState systemState("storage:4");
-
Distribution distr(Distribution::getDefaultDistributionConfig(2, 4));
-
document::BucketId bucket(16, 0x8b4f67ae);
-
res2 = distr.getIdealStorageNodes(systemState, bucket);
EXPECT_EQ(size_t(2), res2.size());
}
@@ -506,8 +475,7 @@ TEST(DistributionTest, test_move_constraints)
std::vector<std::vector<uint16_t> > initBuckets(10000);
for (unsigned i = 0; i < initBuckets.size(); i++) {
- initBuckets[i] = distr.getIdealStorageNodes(
- clusterState, document::BucketId(16, i));
+ initBuckets[i] = distr.getIdealStorageNodes(clusterState, document::BucketId(16, i));
sort(initBuckets[i].begin(), initBuckets[i].end());
}
@@ -517,8 +485,7 @@ TEST(DistributionTest, test_move_constraints)
ClusterState systemState("storage:11 .10.s:d");
for (unsigned i = 0; i < addedDownBuckets.size(); i++) {
- addedDownBuckets[i] = distr.getIdealStorageNodes(
- systemState, document::BucketId(16, i));
+ addedDownBuckets[i] = distr.getIdealStorageNodes(systemState, document::BucketId(16, i));
sort(addedDownBuckets[i].begin(), addedDownBuckets[i].end());
}
for (unsigned i = 0; i < initBuckets.size(); i++) {
@@ -541,15 +508,14 @@ TEST(DistributionTest, test_move_constraints)
ClusterState systemState("storage:10 .0.s:d");
for (unsigned i = 0; i < removed0Buckets.size(); i++) {
- removed0Buckets[i] = distr.getIdealStorageNodes(
- systemState, document::BucketId(16, i));
+ removed0Buckets[i] = distr.getIdealStorageNodes(systemState, document::BucketId(16, i));
sort(removed0Buckets[i].begin(), removed0Buckets[i].end());
}
for (unsigned i = 0; i < initBuckets.size(); i++) {
std::vector<uint16_t> movedAway;
set_difference(initBuckets[i].begin(), initBuckets[i].end(),
- removed0Buckets[i].begin(), removed0Buckets[i].end(),
- back_inserter(movedAway));
+ removed0Buckets[i].begin(), removed0Buckets[i].end(),
+ back_inserter(movedAway));
if (movedAway.size() > 0) {
if (movedAway[0] != 0) {
std::cerr << i << ": ";
@@ -572,15 +538,14 @@ TEST(DistributionTest, test_move_constraints)
ClusterState systemState("storage:11");
for (unsigned i = 0; i < added10Buckets.size(); i++) {
- added10Buckets[i] = distr.getIdealStorageNodes(
- systemState, document::BucketId(16, i));
+ added10Buckets[i] = distr.getIdealStorageNodes(systemState, document::BucketId(16, i));
sort(added10Buckets[i].begin(), added10Buckets[i].end());
}
for (unsigned i = 0; i < initBuckets.size(); i++) {
std::vector<uint16_t> movedInto;
std::set_difference(added10Buckets[i].begin(), added10Buckets[i].end(),
- initBuckets[i].begin(), initBuckets[i].end(),
- std::inserter(movedInto, movedInto.begin()));
+ initBuckets[i].begin(), initBuckets[i].end(),
+ std::inserter(movedInto, movedInto.begin()));
if (movedInto.size() > 0) {
ASSERT_EQ((size_t)1, movedInto.size());
EXPECT_EQ((uint16_t)10, movedInto[0]);
@@ -601,11 +566,9 @@ TEST(DistributionTest, test_distribution_bits)
for (unsigned i = 0; i < 100; i++) {
int val = rand();
- uint32_t index = distr.getIdealDistributorNode(
- state1, document::BucketId(19, val), "u");
+ uint32_t index = distr.getIdealDistributorNode(state1, document::BucketId(19, val), "u");
ost1 << index << " ";
- index = distr.getIdealDistributorNode(
- state2, document::BucketId(19, val), "u");
+ index = distr.getIdealDistributorNode(state2, document::BucketId(19, val), "u");
ost2 << index << " ";
}
@@ -620,10 +583,8 @@ TEST(DistributionTest, test_redundancy_hierarchical_distribution)
Distribution distr2(Distribution::getDefaultDistributionConfig(2, 10));
for (unsigned i = 0; i < 100; i++) {
- uint16_t d1 = distr1.getIdealDistributorNode(
- state, document::BucketId(16, i), "u");
- uint16_t d2 = distr2.getIdealDistributorNode(
- state, document::BucketId(16, i), "u");
+ uint16_t d1 = distr1.getIdealDistributorNode(state, document::BucketId(16, i), "u");
+ uint16_t d2 = distr2.getIdealDistributorNode(state, document::BucketId(16, i), "u");
EXPECT_EQ(d1, d2);
}
}
@@ -653,20 +614,17 @@ TEST(DistributionTest, test_hierarchical_distribution)
ClusterState state("distributor:6 storage:6");
for (uint32_t i = 0; i < 3; ++i) {
- EXPECT_EQ(
- vespalib::string("rack0"),
- distr.getNodeGraph().getGroupForNode(i)->getName());
+ EXPECT_EQ(vespalib::string("rack0"),
+ distr.getNodeGraph().getGroupForNode(i)->getName());
}
for (uint32_t i = 3; i < 6; ++i) {
- EXPECT_EQ(
- vespalib::string("rack1"),
- distr.getNodeGraph().getGroupForNode(i)->getName());
+ EXPECT_EQ(vespalib::string("rack1"),
+ distr.getNodeGraph().getGroupForNode(i)->getName());
}
std::vector<int> mainNode(6);
for (uint32_t i=0; i<100; ++i) {
- std::vector<uint16_t> nodes = distr.getIdealStorageNodes(
- state, document::BucketId(16, i), "u");
+ std::vector<uint16_t> nodes = distr.getIdealStorageNodes(state, document::BucketId(16, i), "u");
ASSERT_EQ((size_t) 4, nodes.size());
EXPECT_LT(nodes[0], mainNode.size());
++mainNode[nodes[0]];
@@ -710,8 +668,7 @@ TEST(DistributionTest, test_group_capacity)
int group0count = 0;
int group1count = 0;
for (uint32_t i = 0; i < 1000; i++) {
- std::vector<uint16_t> nodes = distr.getIdealStorageNodes(
- state, document::BucketId(16, i), "u");
+ std::vector<uint16_t> nodes = distr.getIdealStorageNodes(state, document::BucketId(16, i), "u");
if (nodes[0] == 0 || nodes[0] == 1 || nodes[0] == 2) {
group0count++;
}
@@ -794,14 +751,12 @@ TEST(DistributionTest, test_hierarchical_no_redistribution)
EXPECT_EQ(numBuckets, v.size());
v.clear();
- state.setNodeState(Node(NodeType::STORAGE, 0),
- NodeState(NodeType::STORAGE, State::DOWN));
+ state.setNodeState(Node(NodeType::STORAGE, 0),NodeState(NodeType::STORAGE, State::DOWN));
std::vector< std::vector<uint16_t> > distr2(4);
for (size_t i = 0; i < numBuckets; i++) {
- nodes = distribution.getIdealStorageNodes(
- state, document::BucketId(16, i), "u");
+ nodes = distribution.getIdealStorageNodes(state, document::BucketId(16, i), "u");
for (uint16_t j=0; j<nodes.size(); ++j) {
ASSERT_TRUE(0 != nodes[j]);
distr2[nodes[j]].push_back(i);
@@ -1010,7 +965,7 @@ group[2].nodes[1].retired false
auto nodes_of = [&](uint32_t bucket){
std::vector<uint16_t> actual;
- distr.getIdealNodes(NodeType::STORAGE, state, document::BucketId(16, bucket), actual);
+ distr.getIdealNodes(NodeType::STORAGE, state, document::BucketId(16, bucket), actual, "uim");
return actual;
};
@@ -1071,7 +1026,7 @@ TEST(DistributionTest, DISABLED_benchmark_ideal_state_for_many_groups) {
std::vector<uint16_t> actual;
uint32_t bucket = 0;
auto min_time = vespalib::BenchmarkTimer::benchmark([&]{
- distr.getIdealNodes(NodeType::STORAGE, state, document::BucketId(16, (bucket++ & 0xffffU)), actual);
+ distr.getIdealNodes(NodeType::STORAGE, state, document::BucketId(16, (bucket++ & 0xffffU)), actual, "uim");
}, 5.0);
fprintf(stderr, "%.10f seconds\n", min_time);
}
diff --git a/vdslib/src/vespa/vdslib/distribution/distribution.cpp b/vdslib/src/vespa/vdslib/distribution/distribution.cpp
index 9dda360eea5..87a1f6d3758 100644
--- a/vdslib/src/vespa/vdslib/distribution/distribution.cpp
+++ b/vdslib/src/vespa/vdslib/distribution/distribution.cpp
@@ -20,16 +20,19 @@ LOG_SETUP(".vdslib.distribution");
namespace storage::lib {
namespace {
- std::vector<uint32_t> getDistributionBitMasks() {
- std::vector<uint32_t> masks;
- masks.resize(32 + 1);
- uint32_t mask = 0;
- for (uint32_t i=0; i<=32; ++i) {
- masks[i] = mask;
- mask = (mask << 1) | 1;
- }
- return masks;
+
+std::vector<uint32_t>
+getDistributionBitMasks() {
+ std::vector<uint32_t> masks;
+ masks.resize(32 + 1);
+ uint32_t mask = 0;
+ for (uint32_t i=0; i<=32; ++i) {
+ masks[i] = mask;
+ mask = (mask << 1) | 1;
}
+ return masks;
+}
+
}
VESPA_IMPLEMENT_EXCEPTION(NoDistributorsAvailableException, vespalib::Exception);
@@ -65,8 +68,8 @@ Distribution::Distribution(const Distribution& d)
configure(*reader.read());
}
-Distribution::ConfigWrapper::ConfigWrapper(std::unique_ptr<DistributionConfig> cfg) :
- _cfg(std::move(cfg))
+Distribution::ConfigWrapper::ConfigWrapper(std::unique_ptr<DistributionConfig> cfg) noexcept
+ : _cfg(std::move(cfg))
{ }
Distribution::ConfigWrapper::~ConfigWrapper() = default;
@@ -150,8 +153,7 @@ Distribution::configure(const vespa::config::content::StorDistributionConfig& co
if ( ! nodeGraph) {
throw vespalib::IllegalStateException(
"Got config that didn't seem to specify even a root group. Must "
- "have a root group at minimum:\n"
- + _serialized, VESPA_STRLOC);
+ "have a root group at minimum:\n" + _serialized, VESPA_STRLOC);
}
nodeGraph->calculateDistributionHashValues();
_nodeGraph = std::move(nodeGraph);
@@ -161,14 +163,11 @@ Distribution::configure(const vespa::config::content::StorDistributionConfig& co
_ensurePrimaryPersisted = config.ensurePrimaryPersisted;
_readyCopies = config.readyCopies;
_activePerGroup = config.activePerLeafGroup;
- _distributorAutoOwnershipTransferOnWholeGroupDown
- = config.distributorAutoOwnershipTransferOnWholeGroupDown;
+ _distributorAutoOwnershipTransferOnWholeGroupDown = config.distributorAutoOwnershipTransferOnWholeGroupDown;
}
uint32_t
-Distribution::getGroupSeed(
- const document::BucketId& bucket, const ClusterState& clusterState,
- const Group& group) const
+Distribution::getGroupSeed(const document::BucketId& bucket, const ClusterState& clusterState, const Group& group) const
{
uint32_t seed(static_cast<uint32_t>(bucket.getRawId())
& _distributionBitMasks[clusterState.getDistributionBitCount()]);
@@ -177,8 +176,7 @@ Distribution::getGroupSeed(
}
uint32_t
-Distribution::getDistributorSeed(
- const document::BucketId& bucket, const ClusterState& state) const
+Distribution::getDistributorSeed(const document::BucketId& bucket, const ClusterState& state) const
{
uint32_t seed(static_cast<uint32_t>(bucket.getRawId())
& _distributionBitMasks[state.getDistributionBitCount()]);
@@ -186,8 +184,7 @@ Distribution::getDistributorSeed(
}
uint32_t
-Distribution::getStorageSeed(
- const document::BucketId& bucket, const ClusterState& state) const
+Distribution::getStorageSeed(const document::BucketId& bucket, const ClusterState& state) const
{
uint32_t seed(static_cast<uint32_t>(bucket.getRawId())
& _distributionBitMasks[state.getDistributionBitCount()]);
@@ -262,11 +259,8 @@ namespace {
}
void
-Distribution::getIdealGroups(const document::BucketId& bucket,
- const ClusterState& clusterState,
- const Group& parent,
- uint16_t redundancy,
- std::vector<ResultGroup>& results) const
+Distribution::getIdealGroups(const document::BucketId& bucket, const ClusterState& clusterState, const Group& parent,
+ uint16_t redundancy, std::vector<ResultGroup>& results) const
{
if (parent.isLeafGroup()) {
results.emplace_back(parent, redundancy);
@@ -300,15 +294,12 @@ Distribution::getIdealGroups(const document::BucketId& bucket,
// This should never happen. Config should verify that each group
// has enough groups beneath them.
assert(group._group != nullptr);
- getIdealGroups(bucket, clusterState, *group._group,
- redundancyArray[i], results);
+ getIdealGroups(bucket, clusterState, *group._group, redundancyArray[i], results);
}
}
const Group*
-Distribution::getIdealDistributorGroup(const document::BucketId& bucket,
- const ClusterState& clusterState,
- const Group& parent) const
+Distribution::getIdealDistributorGroup(const document::BucketId& bucket, const ClusterState& clusterState, const Group& parent) const
{
if (parent.isLeafGroup()) {
return &parent;
@@ -357,12 +348,8 @@ Distribution::allDistributorsDown(const Group& g, const ClusterState& cs)
}
void
-Distribution::getIdealNodes(const NodeType& nodeType,
- const ClusterState& clusterState,
- const document::BucketId& bucket,
- std::vector<uint16_t>& resultNodes,
- const char* upStates,
- uint16_t redundancy) const
+Distribution::getIdealNodes(const NodeType& nodeType, const ClusterState& clusterState, const document::BucketId& bucket,
+ std::vector<uint16_t>& resultNodes, const char* upStates, uint16_t redundancy) const
{
if (redundancy == DEFAULT_REDUNDANCY) redundancy = _redundancy;
resultNodes.clear();
@@ -388,8 +375,7 @@ Distribution::getIdealNodes(const NodeType& nodeType,
const Group* group(getIdealDistributorGroup(bucket, clusterState, *_nodeGraph));
if (group == nullptr) {
vespalib::asciistream ss;
- ss << "There is no legal distributor target in state with version "
- << clusterState.getVersion();
+ ss << "There is no legal distributor target in state with version " << clusterState.getVersion();
throw NoDistributorsAvailableException(ss.str(), VESPA_STRLOC);
}
_groupDistribution.push_back(ResultGroup(*group, 1));
@@ -474,15 +460,14 @@ Distribution::getIdealDistributorNode(const ClusterState& state, const document:
assert(nodes.size() <= 1);
if (nodes.empty()) {
vespalib::asciistream ss;
- ss << "There is no legal distributor target in state with version "
- << state.getVersion();
+ ss << "There is no legal distributor target in state with version " << state.getVersion();
throw NoDistributorsAvailableException(ss.str(), VESPA_STRLOC);
}
return nodes[0];
}
std::vector<Distribution::IndexList>
-Distribution::splitNodesIntoLeafGroups(IndexList nodeList) const
+Distribution::splitNodesIntoLeafGroups(vespalib::ConstArrayRef<uint16_t> nodeList) const
{
std::vector<IndexList> result;
std::map<uint16_t, IndexList> nodes;
diff --git a/vdslib/src/vespa/vdslib/distribution/distribution.h b/vdslib/src/vespa/vdslib/distribution/distribution.h
index 355b87884c1..b39afb17e15 100644
--- a/vdslib/src/vespa/vdslib/distribution/distribution.h
+++ b/vdslib/src/vespa/vdslib/distribution/distribution.h
@@ -12,6 +12,7 @@
#include <vespa/document/bucket/bucketid.h>
#include <vespa/vdslib/state/nodetype.h>
#include <vespa/vespalib/util/exception.h>
+#include <vespa/vespalib/util/arrayref.h>
namespace vespa::config::content::internal {
class InternalStorDistributionType;
@@ -38,9 +39,9 @@ private:
uint16_t _redundancy;
uint16_t _initialRedundancy;
uint16_t _readyCopies;
- bool _activePerGroup;
- bool _ensurePrimaryPersisted;
- bool _distributorAutoOwnershipTransferOnWholeGroupDown;
+ bool _activePerGroup;
+ bool _ensurePrimaryPersisted;
+ bool _distributorAutoOwnershipTransferOnWholeGroupDown;
vespalib::string _serialized;
struct ResultGroup {
@@ -50,7 +51,7 @@ private:
ResultGroup(const Group& group, uint16_t redundancy) noexcept
: _group(&group), _redundancy(redundancy) {}
- bool operator<(const ResultGroup& other) const {
+ bool operator<(const ResultGroup& other) const noexcept {
return _group->getIndex() < other._group->getIndex();
}
};
@@ -59,32 +60,23 @@ private:
* Get seed to use for ideal state algorithm's random number generator
* to decide which hierarchical group we should pick.
*/
- uint32_t getGroupSeed(
- const document::BucketId&, const ClusterState&,
- const Group&) const;
+ uint32_t getGroupSeed(const document::BucketId&, const ClusterState&, const Group&) const;
/**
* Get seed to use for ideal state algorithm's random number generator
* to decide which distributor node this bucket should be mapped to.
*/
- uint32_t getDistributorSeed(
- const document::BucketId&, const ClusterState&) const;
+ uint32_t getDistributorSeed(const document::BucketId&, const ClusterState&) const;
/**
* Get seed to use for ideal state algorithm's random number generator
* to decide which storage node this bucket should be mapped to.
*/
- uint32_t getStorageSeed(
- const document::BucketId&, const ClusterState&) const;
+ uint32_t getStorageSeed(const document::BucketId&, const ClusterState&) const;
- void getIdealGroups(const document::BucketId& bucket,
- const ClusterState& clusterState,
- const Group& parent,
- uint16_t redundancy,
- std::vector<ResultGroup>& results) const;
+ void getIdealGroups(const document::BucketId& bucket, const ClusterState& clusterState, const Group& parent,
+ uint16_t redundancy, std::vector<ResultGroup>& results) const;
- const Group* getIdealDistributorGroup(const document::BucketId& bucket,
- const ClusterState& clusterState,
- const Group& parent) const;
+ const Group* getIdealDistributorGroup(const document::BucketId& bucket, const ClusterState& clusterState, const Group& parent) const;
/**
* Since distribution object may be used often in ideal state calculations
@@ -97,9 +89,9 @@ private:
public:
class ConfigWrapper {
public:
- ConfigWrapper(ConfigWrapper && rhs) = default;
- ConfigWrapper & operator = (ConfigWrapper && rhs) = default;
- ConfigWrapper(std::unique_ptr<DistributionConfig> cfg);
+ ConfigWrapper(ConfigWrapper && rhs) noexcept = default;
+ ConfigWrapper & operator = (ConfigWrapper && rhs) noexcept = default;
+ ConfigWrapper(std::unique_ptr<DistributionConfig> cfg) noexcept;
~ConfigWrapper();
const DistributionConfig & get() const { return *_cfg; }
private:
@@ -114,33 +106,26 @@ public:
Distribution& operator=(const Distribution&) = delete;
- const vespalib::string& serialize() const { return _serialized; }
+ const vespalib::string& serialize() const noexcept { return _serialized; }
- const Group& getNodeGraph() const { return *_nodeGraph; }
- uint16_t getRedundancy() const { return _redundancy; }
- uint16_t getInitialRedundancy() const { return _initialRedundancy; }
- uint16_t getReadyCopies() const { return _readyCopies; }
- bool ensurePrimaryPersisted() const { return _ensurePrimaryPersisted; }
- bool distributorAutoOwnershipTransferOnWholeGroupDown() const
- { return _distributorAutoOwnershipTransferOnWholeGroupDown; }
- bool activePerGroup() const { return _activePerGroup; }
+ const Group& getNodeGraph() const noexcept { return *_nodeGraph; }
+ uint16_t getRedundancy() const noexcept { return _redundancy; }
+ uint16_t getInitialRedundancy() const noexcept { return _initialRedundancy; }
+ uint16_t getReadyCopies() const noexcept { return _readyCopies; }
+ bool ensurePrimaryPersisted() const noexcept { return _ensurePrimaryPersisted; }
+ bool distributorAutoOwnershipTransferOnWholeGroupDown() const noexcept { return _distributorAutoOwnershipTransferOnWholeGroupDown; }
+ bool activePerGroup() const noexcept { return _activePerGroup; }
- bool operator==(const Distribution& o) const
- { return (_serialized == o._serialized); }
- bool operator!=(const Distribution& o) const
- { return (_serialized != o._serialized); }
+ bool operator==(const Distribution& o) const noexcept { return (_serialized == o._serialized); }
+ bool operator!=(const Distribution& o) const noexcept { return (_serialized != o._serialized); }
void print(std::ostream& out, bool, const std::string&) const override;
/** Simplified wrapper for getIdealNodes() */
- std::vector<uint16_t> getIdealStorageNodes(
- const ClusterState&, const document::BucketId&,
- const char* upStates = "uim") const;
+ std::vector<uint16_t> getIdealStorageNodes(const ClusterState&, const document::BucketId&, const char* upStates = "uim") const;
/** Simplified wrapper for getIdealNodes() */
- uint16_t getIdealDistributorNode(
- const ClusterState&, const document::BucketId&,
- const char* upStates = "uim") const;
+ uint16_t getIdealDistributorNode(const ClusterState&, const document::BucketId&, const char* upStates = "uim") const;
/**
* @throws TooFewBucketBitsInUseException If distribution bit count is
@@ -149,25 +134,22 @@ public:
* in any upstate.
*/
enum { DEFAULT_REDUNDANCY = 0xffff };
- void getIdealNodes(const NodeType&, const ClusterState&,
- const document::BucketId&, std::vector<uint16_t>& nodes,
- const char* upStates = "uim",
- uint16_t redundancy = DEFAULT_REDUNDANCY) const;
+ void getIdealNodes(const NodeType&, const ClusterState&, const document::BucketId&, std::vector<uint16_t>& nodes,
+ const char* upStates, uint16_t redundancy = DEFAULT_REDUNDANCY) const;
/**
* Unit tests can use this function to get raw config for this class to use
* with a really simple setup with no hierarchical grouping. This function
* should not be used by any production code.
*/
- static ConfigWrapper getDefaultDistributionConfig(
- uint16_t redundancy = 2, uint16_t nodeCount = 10);
+ static ConfigWrapper getDefaultDistributionConfig(uint16_t redundancy = 2, uint16_t nodeCount = 10);
/**
* Utility function used by distributor to split copies into groups to
* handle active per group feature.
*/
using IndexList = std::vector<uint16_t>;
- std::vector<IndexList> splitNodesIntoLeafGroups(IndexList nodes) const;
+ std::vector<IndexList> splitNodesIntoLeafGroups(vespalib::ConstArrayRef<uint16_t> nodes) const;
static bool allDistributorsDown(const Group&, const ClusterState&);
};