summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-09-29 16:20:45 +0200
committerGitHub <noreply@github.com>2021-09-29 16:20:45 +0200
commit1bc2cca4b527bb9a5a8c67744b0796c9fafbe024 (patch)
tree5287388c481896feca18fa34b06ac98fc11cdcf8
parent3ea56620ec4bd3301dbc2dda85334b00e2972490 (diff)
parent69763ec7a8063ec730c5ca35f64873741df4e6b5 (diff)
Merge pull request #19355 from vespa-engine/balder/precompute-unused-ipadresses
Cheaper compute of free ip adresses.
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodesAndHosts.java25
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/IP.java21
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostCapacity.java2
3 files changed, 24 insertions, 24 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodesAndHosts.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodesAndHosts.java
index 5cf9d297c15..cdf117c11ce 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodesAndHosts.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodesAndHosts.java
@@ -1,11 +1,16 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision;
+import com.yahoo.vespa.hosted.provision.node.IP;
+
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* Wraps a NodeList and builds a host to children mapping for faster access
@@ -15,7 +20,9 @@ import java.util.Optional;
*/
public class NodesAndHosts<NL extends NodeList> {
private final NL nodes;
- private final Map<String, HostAndNodes> host2Nodes;
+ private final Map<String, HostAndNodes> host2Nodes = new HashMap<>();
+ private final Set<String> allPrimaryIps = new HashSet<>();
+ private final Set<String> allHostNames;
public static <L extends NodeList> NodesAndHosts<L> create(L nodes) {
return new NodesAndHosts<L>(nodes);
@@ -23,12 +30,14 @@ public class NodesAndHosts<NL extends NodeList> {
private NodesAndHosts(NL nodes) {
this.nodes = nodes;
- host2Nodes = new HashMap<>();
+ nodes.forEach(node -> node.ipConfig().primary().forEach(ip -> allPrimaryIps.add(ip)));
+ allHostNames = nodes.stream().map(Node::hostname).collect(Collectors.toSet());
nodes.forEach(node -> {
node.parentHostname().ifPresentOrElse(
parent -> host2Nodes.computeIfAbsent(parent, key -> new HostAndNodes()).add(node),
() -> host2Nodes.computeIfAbsent(node.hostname(), key -> new HostAndNodes()).setHost(node));
});
+
}
/// Return the NodeList used for construction
@@ -46,6 +55,18 @@ public class NodesAndHosts<NL extends NodeList> {
return hostAndNodes != null ? Optional.ofNullable(hostAndNodes.host) : Optional.empty();
}
+ /**
+ * Returns the number of unused IP addresses in the pool, assuming any and all unaccounted for hostnames
+ * in the pool are resolved to exactly 1 IP address (or 2 with {@link IP.IpAddresses.Protocol#dualStack}).
+ */
+ public int eventuallyUnusedIpAddressCount(Node host) {
+ // The count in this method relies on the size of the IP address pool if that's non-empty,
+ // otherwise fall back to the address/hostname pool.
+ return (int) (host.ipConfig().pool().ipSet().isEmpty()
+ ? host.ipConfig().pool().getAddressList().stream().filter(address -> !allHostNames.contains(address.hostname())).count()
+ : host.ipConfig().pool().ipSet().stream().filter(address -> !allPrimaryIps.contains(address)).count());
+ }
+
private static class HostAndNodes {
private Node host;
private final List<Node> children;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/IP.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/IP.java
index 1b7c629416a..bc667e146dc 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/IP.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/IP.java
@@ -307,27 +307,6 @@ public class IP {
return Collections.unmodifiableSet(unusedAddresses);
}
- /**
- * Returns the number of unused IP addresses in the pool, assuming any and all unaccounted for hostnames
- * in the pool are resolved to exactly 1 IP address (or 2 with {@link IpAddresses.Protocol#dualStack}).
- */
- public int eventuallyUnusedAddressCount(NodeList nodes) {
- // The address pool is filled immediately upon provisioning in dynamically provisioned zones,
- // and within short time the IP address pool is filled. For all other cases, the IP address
- // pool is already filled.
- //
- // The count in this method relies on the size of the IP address pool if that's non-empty,
- // otherwise fall back to the address/hostname pool.
-
-
- Set<String> currentIpAddresses = this.ipAddresses.asSet();
- if (!currentIpAddresses.isEmpty()) {
- return findUnusedIpAddresses(nodes).size();
- }
-
- return (int) findUnusedAddressStream(nodes).count();
- }
-
private Stream<Address> findUnusedAddressStream(NodeList nodes) {
Set<String> hostnames = nodes.stream().map(Node::hostname).collect(Collectors.toSet());
return addresses.stream().filter(address -> !hostnames.contains(address.hostname()));
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostCapacity.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostCapacity.java
index bc2d606aa63..f234db86da3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostCapacity.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostCapacity.java
@@ -97,7 +97,7 @@ public class HostCapacity {
/** Returns the number of available IP addresses on given host */
int freeIps(Node host) {
if (host.type() == NodeType.host) {
- return host.ipConfig().pool().eventuallyUnusedAddressCount(allNodes.nodes());
+ return (allNodes.eventuallyUnusedIpAddressCount(host));
}
return host.ipConfig().pool().findUnusedIpAddresses(allNodes.nodes()).size();
}