diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-29 13:11:24 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-29 16:10:20 +0200 |
commit | 69763ec7a8063ec730c5ca35f64873741df4e6b5 (patch) | |
tree | 5287388c481896feca18fa34b06ac98fc11cdcf8 | |
parent | 3ea56620ec4bd3301dbc2dda85334b00e2972490 (diff) |
Cheaper compute of free ip adresses.
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(); } |