private int totalAllocatedTo(ClusterSpec cluster) { int count = 0; for (Map.Entry<ClusterSpec, List<HostSpec>> allocation : allocations.entrySet()) { if ( ! allocation.getKey().type().equals(cluster.type())) continue; if ( ! allocation.getKey().id().equals(cluster.id())) continue; count += allocation.getValue().size(); } return count; }
@Override public boolean equals(Object o) { if (o == this) return true; if ( ! (o instanceof ClusterSpec)) return false; ClusterSpec other = (ClusterSpec)o; if ( ! other.type.equals(this.type)) return false; if ( ! other.id.equals(this.id)) return false; if ( ! other.groupId.equals(this.groupId)) return false; if ( ! other.vespaVersion.equals(this.vespaVersion)) return false; return true; }
/** * Returns a list of the nodes which are * in groups with index number above or equal the group count */ private List<Node> findNodesInRemovableGroups(ApplicationId application, ClusterSpec requestedCluster, int wantedGroups) { List<Node> surplusNodes = new ArrayList<>(0); for (Node node : nodeRepository.getNodes(application, Node.State.active)) { ClusterSpec nodeCluster = node.allocation().get().membership().cluster(); if ( ! nodeCluster.id().equals(requestedCluster.id())) continue; if ( ! nodeCluster.type().equals(requestedCluster.type())) continue; if (nodeCluster.group().get().index() >= wantedGroups) surplusNodes.add(node); } return surplusNodes; }
private static int compareForRelocation(Node a, Node b) { // Choose smallest node int capacity = ResourceCapacity.of(a).compare(ResourceCapacity.of(b)); if (capacity != 0) return capacity; // Choose unallocated over allocated (this case is when we have ready docker nodes) if (!a.allocation().isPresent() && b.allocation().isPresent()) return -1; if (a.allocation().isPresent() && !b.allocation().isPresent()) return 1; // Choose container over content nodes if (a.allocation().isPresent() && b.allocation().isPresent()) { if (a.allocation().get().membership().cluster().type().equals(ClusterSpec.Type.container) && !b.allocation().get().membership().cluster().type().equals(ClusterSpec.Type.container)) return -1; if (!a.allocation().get().membership().cluster().type().equals(ClusterSpec.Type.container) && b.allocation().get().membership().cluster().type().equals(ClusterSpec.Type.container)) return 1; } // To get a stable algorithm - choose lexicographical from hostname return a.hostname().compareTo(b.hostname()); }
/** * Returns the highest index number of all active and failed nodes in this cluster, or -1 if there are no nodes. * We include failed nodes to avoid reusing the index of the failed node in the case where the failed node is the * node with the highest index. */ private int findHighestIndex(ApplicationId application, ClusterSpec cluster) { int highestIndex = -1; for (Node node : nodeRepository.getNodes(application, Node.State.active, Node.State.inactive, Node.State.parked, Node.State.failed)) { ClusterSpec nodeCluster = node.allocation().get().membership().cluster(); if ( ! nodeCluster.id().equals(cluster.id())) continue; if ( ! nodeCluster.type().equals(cluster.type())) continue; highestIndex = Math.max(node.allocation().get().membership().index(), highestIndex); } return highestIndex; }
/** Returns whether this is equal, disregarding the group value and wanted Vespa version */ public boolean equalsIgnoringGroupAndVespaVersion(Object o) { if (o == this) return true; if ( ! (o instanceof ClusterSpec)) return false; ClusterSpec other = (ClusterSpec)o; if ( ! other.type.equals(this.type)) return false; if ( ! other.id.equals(this.id)) return false; return true; }
/** Returns the subset of nodes assigned to the given cluster type */ public NodeList type(ClusterSpec.Type type) { return filter(node -> node.allocation().get().membership().cluster().type().equals(type)); }