diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2022-08-03 17:35:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-03 17:35:11 +0200 |
commit | cc0e0a6919a4fccd7ef6d6016ba186136d49c956 (patch) | |
tree | af409afdb07d6fe2290124ae7b57ee1dba767d9b /node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java | |
parent | 66df56662aaa775732c5b2f23c49ffaed668a276 (diff) | |
parent | 38f54c8d1ae746377ce2260c39a9cce377148e84 (diff) |
Merge pull request #23573 from vespa-engine/bratseth/autoscale-faster
Bratseth/autoscale faster
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java')
-rw-r--r-- | node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java index a52b048a9e0..88c7e70cd35 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Load.java @@ -3,6 +3,12 @@ package com.yahoo.vespa.hosted.provision.autoscale; import com.yahoo.config.provision.NodeResources; +import java.util.Objects; +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleFunction; +import java.util.function.DoubleUnaryOperator; +import java.util.function.Predicate; + /** * The load of a node or system, measured as fractions of max (1.0) in three dimensions. * @@ -10,6 +16,8 @@ import com.yahoo.config.provision.NodeResources; */ public class Load { + public enum Dimension { cpu, memory, disk } + private final double cpu, memory, disk; public Load(double cpu, double memory, double disk) { @@ -23,27 +31,51 @@ public class Load { public double disk() { return disk; } public Load add(Load other) { - return new Load(cpu + other.cpu(), memory + other.memory(), disk + other.disk()); + return join(other, (a, b) -> a + b); } public Load multiply(NodeResources resources) { return new Load(cpu * resources.vcpu(), memory * resources.memoryGb(), disk * resources.diskGb()); } - public Load multiply(double factor) { - return new Load(cpu * factor, memory * factor, disk * factor); + return map(v -> v * factor); + } + public Load multiply(Load other) { + return join(other, (a, b) -> a * b); } + public Load divide(Load divisor) { + return join(divisor, (a, b) -> divide(a, b)); + } + public Load divide(double divisor) { + return map(v -> divide(v, divisor)); + } public Load divide(NodeResources resources) { return new Load(divide(cpu, resources.vcpu()), divide(memory, resources.memoryGb()), divide(disk, resources.diskGb())); } - public Load divide(Load divisor) { - return new Load(divide(cpu, divisor.cpu()), divide(memory, divisor.memory()), divide(disk, divisor.disk())); + /** Returns the load having the max value of this and the given load in each dimension. */ + public Load max(Load other) { + return join(other, (a, b) -> Math.max(a, b)); } - public Load divide(double divisor) { - return new Load(divide(cpu, divisor), divide(memory, divisor), divide(disk, divisor)); + /** Returns the load where the given function is applied to each dimension of this. */ + public Load map(DoubleUnaryOperator f) { + return new Load(f.applyAsDouble(cpu), + f.applyAsDouble(memory), + f.applyAsDouble(disk)); + } + + /** Returns the load where the given function is applied to each dimension of this and the given load. */ + public Load join(Load other, DoubleBinaryOperator f) { + return new Load(f.applyAsDouble(this.cpu(), other.cpu()), + f.applyAsDouble(this.memory(), other.memory()), + f.applyAsDouble(this.disk(), other.disk())); + } + + /** Returns true if any dimension matches the predicate. */ + public boolean any(Predicate<Double> test) { + return test.test(cpu) || test.test(memory) || test.test(disk); } public NodeResources scaled(NodeResources resources) { @@ -52,6 +84,14 @@ public class Load { .withDiskGb(disk * resources.diskGb()); } + public double get(Dimension dimension) { + return switch (dimension) { + case cpu -> cpu(); + case memory -> memory(); + case disk -> disk(); + }; + } + private double requireNormalized(double value, String name) { if (Double.isNaN(value)) throw new IllegalArgumentException(name + " must be a number but is NaN"); @@ -60,17 +100,31 @@ public class Load { return value; } + private static double divide(double a, double b) { + if (a == 0 && b == 0) return 0; + return a / b; + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if ( ! (o instanceof Load other)) return false; + if (other.cpu() != this.cpu()) return false; + if (other.memory() != this.memory()) return false; + if (other.disk() != this.disk()) return false; + return true; + } + + @Override + public int hashCode() { return Objects.hash(cpu, memory, disk); } + @Override public String toString() { return "load: " + cpu + " cpu, " + memory + " memory, " + disk + " disk"; } public static Load zero() { return new Load(0, 0, 0); } - - private static double divide(double a, double b) { - if (a == 0 && b == 0) return 0; - return a / b; - } + public static Load one() { return new Load(1, 1, 1); } public static Load byDividing(NodeResources a, NodeResources b) { return new Load(divide(a.vcpu(), b.vcpu()), divide(a.memoryGb(), b.memoryGb()), divide(a.diskGb(), b.diskGb())); |