private void validate(ClusterSpec cluster, ChangeContext context) {
        ClusterResources current = clusterResources(cluster.id(), context.previousModel());
        ClusterResources next = clusterResources(cluster.id(), context.model());
        if (current == null || next == null) return;

        double loadIncreasePerNode;
        StringBuilder changes = new StringBuilder();
        if ( ! cluster.type().isContent()) {
            loadIncreasePerNode = (double)current.nodes() / next.nodes();
            if (current.nodes() != next.nodes())
                changes.append("from ").append(current.nodes()).append(" nodes to ")
                       .append(next.nodes()).append(" nodes").append(", ");
        }
        else { // take data size per node given from redundancy and groups into account
            ContentCluster currentCluster = context.previousModel().getContentClusters().get(cluster.id().value());
            ContentCluster nextCluster = context.model().getContentClusters().get(cluster.id().value());
            loadIncreasePerNode =
                (double) nextCluster.getRedundancy().finalRedundancy() / currentCluster.getRedundancy().finalRedundancy()
                *
                (double) currentCluster.groupSize() / nextCluster.groupSize();
            if (nextCluster.getRedundancy().finalRedundancy() != currentCluster.getRedundancy().finalRedundancy())
                changes.append("redundancy from ").append(currentCluster.getRedundancy().finalRedundancy())
                       .append(" to ").append(nextCluster.getRedundancy().finalRedundancy()).append(", ");
            if (nextCluster.groupSize() != currentCluster.groupSize())
                changes.append("group size from ").append(currentCluster.groupSize())
                       .append(" to ").append(nextCluster.groupSize()).append(" nodes, ");
        }

        if (current.nodeResources().isUnspecified() || next.nodeResources().isUnspecified()) {
            // Self-hosted: We don't know node resources so assume they are constant
            if (loadIncreasePerNode > maxAllowedUtilizationIncrease)
                invalid(changes, cluster, context);
        }
        else {
            NodeResources currentResources = current.nodeResources();
            NodeResources nextResources = next.nodeResources();
            if (invalid(currentResources.vcpu(), nextResources.vcpu(), "vcpu", loadIncreasePerNode, changes)
                || invalid(currentResources.memoryGiB(), nextResources.memoryGiB(), "memory GiB", loadIncreasePerNode, changes)
                || invalid(currentResources.diskGb(), nextResources.diskGb(), "disk Gb", loadIncreasePerNode, changes))
                invalid(changes, cluster, context);
        }
    }
Checks that resources per document per node is reduced too much in one go.

@author bratseth
config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java