
com.yahoo.vespa.hosted.provision.NodesAndHosts Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of node-repository Show documentation
Show all versions of node-repository Show documentation
Keeps track of node assignment in a multi-application setup.
// 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
* as that is done very frequently.
*
* @author baldersheim
*/
public class NodesAndHosts {
private final NL nodes;
private final Map host2Nodes = new HashMap<>();
private final Set allPrimaryIps = new HashSet<>();
private final Set allHostNames;
public static NodesAndHosts create(L nodes) {
return new NodesAndHosts(nodes);
}
private NodesAndHosts(NL nodes) {
this.nodes = nodes;
nodes.forEach(node -> allPrimaryIps.addAll(node.ipConfig().primary()));
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
public NL nodes() { return nodes; }
public NodeList childrenOf(Node host) {
return childrenOf(host.hostname());
}
public NodeList childrenOf(String hostname) {
HostAndNodes hostAndNodes = host2Nodes.get(hostname);
return hostAndNodes != null ? NodeList.copyOf(hostAndNodes.children) : NodeList.of();
}
public Optional parentOf(Node node) {
if (node.parentHostname().isEmpty()) return Optional.empty();
HostAndNodes hostAndNodes = host2Nodes.get(node.parentHostname().get());
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 children;
HostAndNodes() {
this.host = null;
children = new ArrayList<>();
}
void setHost(Node host) { this.host = host; }
void add(Node child) { children.add(child); }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy