diff options
Diffstat (limited to 'vespajlib/src/main/java/com/yahoo/tensor/impl')
8 files changed, 76 insertions, 18 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/Label.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/Label.java index 0ab1454eb58..a09c0223d28 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/Label.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/Label.java @@ -7,16 +7,26 @@ import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +/** + * A label is a value of a mapped dimension of a tensor. + * This class provides a mapping of labels to numbers which allow for more efficient computation with + * mapped tensor dimensions. + * + * @author baldersheim + */ public class Label { - private static final String [] SMALL_INDEXES = createSmallIndexesAsStrings(1000); + + private static final String[] SMALL_INDEXES = createSmallIndexesAsStrings(1000); + private final static Map<String, Integer> string2Enum = new ConcurrentHashMap<>(); + // Index 0 is unused, that is a valid positive number // 1(-1) is reserved for the Tensor.INVALID_INDEX - private static volatile String [] uniqueStrings = {"UNIQUE_UNUSED_MAGIC", "Tensor.INVALID_INDEX"}; + private static volatile String[] uniqueStrings = {"UNIQUE_UNUSED_MAGIC", "Tensor.INVALID_INDEX"}; private static int numUniqeStrings = 2; private static String[] createSmallIndexesAsStrings(int count) { - String [] asStrings = new String[count]; + String[] asStrings = new String[count]; for (int i = 0; i < count; i++) { asStrings[i] = String.valueOf(i); } @@ -46,7 +56,7 @@ public class Label { } public static int toNumber(String s) { - if (s == null) { return Tensor.INVALID_INDEX; } + if (s == null) { return Tensor.invalidIndex; } try { if (validNumericIndex(s)) { return Integer.parseInt(s); @@ -55,14 +65,16 @@ public class Label { } return string2Enum.computeIfAbsent(s, Label::addNewUniqueString); } + public static String fromNumber(int v) { if (v >= 0) { return asNumericString(v); } else { - if (v == Tensor.INVALID_INDEX) { return null; } + if (v == Tensor.invalidIndex) { return null; } return uniqueStrings[-v]; } } + public static String fromNumber(long v) { return fromNumber(Convert.safe2Int(v)); } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny.java index 31863c99a74..2e70811a67c 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny.java @@ -18,6 +18,7 @@ import static com.yahoo.tensor.impl.Label.fromNumber; * @author baldersheim */ abstract public class TensorAddressAny extends TensorAddress { + @Override public String label(int i) { return fromNumber((int)numericLabel(i)); @@ -26,37 +27,47 @@ abstract public class TensorAddressAny extends TensorAddress { public static TensorAddress of() { return TensorAddressEmpty.empty; } + public static TensorAddress of(String label) { return new TensorAddressAny1(toNumber(label)); } + public static TensorAddress of(String label0, String label1) { return new TensorAddressAny2(toNumber(label0), toNumber(label1)); } + public static TensorAddress of(String label0, String label1, String label2) { return new TensorAddressAny3(toNumber(label0), toNumber(label1), toNumber(label2)); } + public static TensorAddress of(String label0, String label1, String label2, String label3) { return new TensorAddressAny4(toNumber(label0), toNumber(label1), toNumber(label2), toNumber(label3)); } - public static TensorAddress of(String [] labels) { - int [] labelsAsInt = new int[labels.length]; + + public static TensorAddress of(String[] labels) { + int[] labelsAsInt = new int[labels.length]; for (int i = 0; i < labels.length; i++) { labelsAsInt[i] = toNumber(labels[i]); } return ofUnsafe(labelsAsInt); } + public static TensorAddress of(int label) { return new TensorAddressAny1(sanitize(label)); } + public static TensorAddress of(int label0, int label1) { return new TensorAddressAny2(sanitize(label0), sanitize(label1)); } + public static TensorAddress of(int label0, int label1, int label2) { return new TensorAddressAny3(sanitize(label0), sanitize(label1), sanitize(label2)); } + public static TensorAddress of(int label0, int label1, int label2, int label3) { return new TensorAddressAny4(sanitize(label0), sanitize(label1), sanitize(label2), sanitize(label3)); } + public static TensorAddress of(int ... labels) { return switch (labels.length) { case 0 -> of(); @@ -72,6 +83,7 @@ abstract public class TensorAddressAny extends TensorAddress { } }; } + public static TensorAddress of(long label) { return of(safe2Int(label)); } @@ -96,7 +108,7 @@ abstract public class TensorAddressAny extends TensorAddress { case 3 -> ofUnsafe(safe2Int(labels[0]), safe2Int(labels[1]), safe2Int(labels[2])); case 4 -> ofUnsafe(safe2Int(labels[0]), safe2Int(labels[1]), safe2Int(labels[2]), safe2Int(labels[3])); default -> { - int [] labelsAsInt = new int[labels.length]; + int[] labelsAsInt = new int[labels.length]; for (int i = 0; i < labels.length; i++) { labelsAsInt[i] = safe2Int(labels[i]); } @@ -108,15 +120,19 @@ abstract public class TensorAddressAny extends TensorAddress { private static TensorAddress ofUnsafe(int label) { return new TensorAddressAny1(label); } + private static TensorAddress ofUnsafe(int label0, int label1) { return new TensorAddressAny2(label0, label1); } + private static TensorAddress ofUnsafe(int label0, int label1, int label2) { return new TensorAddressAny3(label0, label1, label2); } + private static TensorAddress ofUnsafe(int label0, int label1, int label2, int label3) { return new TensorAddressAny4(label0, label1, label2, label3); } + public static TensorAddress ofUnsafe(int ... labels) { return switch (labels.length) { case 0 -> of(); @@ -127,10 +143,12 @@ abstract public class TensorAddressAny extends TensorAddress { default -> new TensorAddressAnyN(labels); }; } + private static int sanitize(int label) { - if (label < Tensor.INVALID_INDEX) { + if (label < Tensor.invalidIndex) { throw new IndexOutOfBoundsException("cell label " + label + " must be positive"); } return label; } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny1.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny1.java index a2b0d318a50..a9be6173781 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny1.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny1.java @@ -5,11 +5,14 @@ package com.yahoo.tensor.impl; import com.yahoo.tensor.TensorAddress; /** - * Single dimension + * A one-dimensional address. + * * @author baldersheim */ final class TensorAddressAny1 extends TensorAddressAny { + private final int label; + TensorAddressAny1(int label) { this.label = label; } @Override public int size() { return 1; } @@ -34,4 +37,5 @@ final class TensorAddressAny1 extends TensorAddressAny { public boolean equals(Object o) { return (o instanceof TensorAddressAny1 any) && (label == any.label); } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny2.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny2.java index d77a689852f..43f65d495cf 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny2.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny2.java @@ -7,11 +7,14 @@ import com.yahoo.tensor.TensorAddress; import static java.lang.Math.abs; /** - * 2 dimensional address + * A two-dimensional address. + * * @author baldersheim */ final class TensorAddressAny2 extends TensorAddressAny { + private final int label0, label1; + TensorAddressAny2(int label0, int label1) { this.label0 = label0; this.label1 = label1; @@ -46,4 +49,5 @@ final class TensorAddressAny2 extends TensorAddressAny { public boolean equals(Object o) { return (o instanceof TensorAddressAny2 any) && (label0 == any.label0) && (label1 == any.label1); } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny3.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny3.java index 95e14bd375c..c22ff47b3c4 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny3.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny3.java @@ -7,11 +7,14 @@ import com.yahoo.tensor.TensorAddress; import static java.lang.Math.abs; /** - * 3 dimensional address + * A three-dimensional address. + * * @author baldersheim */ final class TensorAddressAny3 extends TensorAddressAny { + private final int label0, label1, label2; + TensorAddressAny3(int label0, int label1, int label2) { this.label0 = label0; this.label1 = label1; @@ -54,4 +57,5 @@ final class TensorAddressAny3 extends TensorAddressAny { (label1 == any.label1) && (label2 == any.label2); } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny4.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny4.java index 8a45483340e..6eb6b9216bf 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny4.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAny4.java @@ -7,11 +7,14 @@ import com.yahoo.tensor.TensorAddress; import static java.lang.Math.abs; /** - * 4 dimensional address + * A four-dimensional address. + * * @author baldersheim */ final class TensorAddressAny4 extends TensorAddressAny { + private final int label0, label1, label2, label3; + TensorAddressAny4(int label0, int label1, int label2, int label3) { this.label0 = label0; this.label1 = label1; @@ -59,4 +62,5 @@ final class TensorAddressAny4 extends TensorAddressAny { (label2 == any.label2) && (label3 == any.label3); } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAnyN.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAnyN.java index acd7ed60722..d5bac62bf18 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAnyN.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressAnyN.java @@ -9,22 +9,26 @@ import java.util.Arrays; import static java.lang.Math.abs; /** - * N dimensional address + * An n-dimensional address. + * * @author baldersheim */ final class TensorAddressAnyN extends TensorAddressAny { - private final int [] labels; - TensorAddressAnyN(int [] labels) { + + private final int[] labels; + + TensorAddressAnyN(int[] labels) { if (labels.length < 1) throw new IllegalArgumentException("Need at least 1 label"); this.labels = labels; } @Override public int size() { return labels.length; } + @Override public long numericLabel(int i) { return labels[i]; } @Override public TensorAddress withLabel(int labelIndex, long label) { - int [] copy = Arrays.copyOf(labels, labels.length); + int[] copy = Arrays.copyOf(labels, labels.length); copy[labelIndex] = Convert.safe2Int(label); return new TensorAddressAnyN(copy); } @@ -45,4 +49,5 @@ final class TensorAddressAnyN extends TensorAddressAny { } return true; } + } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressEmpty.java b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressEmpty.java index 2d9cd3eed78..eb7e62e913b 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressEmpty.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/impl/TensorAddressEmpty.java @@ -5,13 +5,18 @@ package com.yahoo.tensor.impl; import com.yahoo.tensor.TensorAddress; /** - * 0 dimesional/empty address + * A zero-dimensional address. + * * @author baldersheim */ final class TensorAddressEmpty extends TensorAddressAny { + static TensorAddress empty = new TensorAddressEmpty(); + private TensorAddressEmpty() {} + @Override public int size() { return 0; } + @Override public long numericLabel(int i) { throw new IllegalArgumentException("Empty address with no labels"); } @Override @@ -21,6 +26,8 @@ final class TensorAddressEmpty extends TensorAddressAny { @Override public int hashCode() { return 0; } + @Override public boolean equals(Object o) { return o instanceof TensorAddressEmpty; } + } |