aboutsummaryrefslogtreecommitdiffstats
path: root/vespajlib/src/main
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2023-03-20 11:26:26 +0100
committerGitHub <noreply@github.com>2023-03-20 11:26:26 +0100
commit47e7d6a7509c5ba3a339afbaa0f17b16d9b382af (patch)
treead511fda70c2bdaffa21311ce3fb069cf95730b3 /vespajlib/src/main
parent89862f601ce193c1b8aa96d9979ad5ef57c1a505 (diff)
parent24b297f12cdb8707d15ad554554eaaff76bcbdd3 (diff)
Merge branch 'master' into arnej/handle-dynamic-tensor
Diffstat (limited to 'vespajlib/src/main')
-rw-r--r--vespajlib/src/main/java/com/yahoo/slime/ArrayValue.java108
1 files changed, 91 insertions, 17 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/slime/ArrayValue.java b/vespajlib/src/main/java/com/yahoo/slime/ArrayValue.java
index dbd9771afe9..9f455a5b7d4 100644
--- a/vespajlib/src/main/java/com/yahoo/slime/ArrayValue.java
+++ b/vespajlib/src/main/java/com/yahoo/slime/ArrayValue.java
@@ -6,9 +6,94 @@ package com.yahoo.slime;
*/
final class ArrayValue extends Value {
- private int capacity = 16;
+ static final int initial_capacity = 16;
+ static final Impl initial_impl = new EmptyImpl();
+
+ private interface Impl {
+ public void prepareFor(ArrayValue self, Type type);
+ public Value add(Value value, int used);
+ public Value get(int index);
+ }
+
+ private static final class EmptyImpl implements Impl {
+ public void prepareFor(ArrayValue self, Type type) {
+ if (type == Type.LONG) {
+ self.impl = new LongImpl();
+ } else if (type == Type.DOUBLE) {
+ self.impl = new DoubleImpl();
+ } else {
+ self.impl = new GenericImpl(this, 0);
+ }
+ }
+ public Value add(Value value, int used) { return NixValue.invalid(); }
+ public Value get(int index) { return NixValue.invalid(); }
+ }
+
+ private static final class LongImpl implements Impl {
+ private long[] values = new long[initial_capacity];
+ public void prepareFor(ArrayValue self, Type type) {
+ if (type != Type.LONG) {
+ self.impl = new GenericImpl(this, self.used);
+ }
+ }
+ public Value add(Value value, int used) {
+ if (used == values.length) {
+ long[] v = values;
+ values = new long[v.length << 1];
+ System.arraycopy(v, 0, values, 0, used);
+ }
+ values[used] = value.asLong();
+ return get(used);
+ }
+ public Value get(int index) { return new LongValue(values[index]); }
+ }
+
+ private static final class DoubleImpl implements Impl {
+ private double[] values = new double[initial_capacity];
+ public void prepareFor(ArrayValue self, Type type) {
+ if (type != Type.DOUBLE) {
+ self.impl = new GenericImpl(this, self.used);
+ }
+ }
+ public Value add(Value value, int used) {
+ if (used == values.length) {
+ double[] v = values;
+ values = new double[v.length << 1];
+ System.arraycopy(v, 0, values, 0, used);
+ }
+ values[used] = value.asDouble();
+ return get(used);
+ }
+ public Value get(int index) { return new DoubleValue(values[index]); }
+ }
+
+ private static final class GenericImpl implements Impl {
+ private Value[] values;
+ GenericImpl(Impl src, int len) {
+ int capacity = initial_capacity;
+ while (capacity < (len + 1)) {
+ capacity = capacity << 1;
+ }
+ values = new Value[capacity];
+ for (int i = 0; i < len; i++) {
+ values[i] = src.get(i);
+ }
+ }
+ public void prepareFor(ArrayValue self, Type type) {}
+ public Value add(Value value, int used) {
+ if (used == values.length) {
+ Value[] v = values;
+ values = new Value[v.length << 1];
+ System.arraycopy(v, 0, values, 0, used);
+ }
+ values[used] = value;
+ return get(used);
+ }
+ public Value get(int index) { return values[index]; }
+ }
+
+ private Impl impl = initial_impl;
private int used = 0;
- private Value[] values = new Value[capacity];
private final SymbolTable names;
public ArrayValue(SymbolTable names) { this.names = names; }
@@ -16,33 +101,22 @@ final class ArrayValue extends Value {
public int children() { return used; }
public int entries() { return used; }
public Value entry(int index) {
- return (index < used) ? values[index] : NixValue.invalid();
+ return (index >= 0 && index < used) ? impl.get(index) : NixValue.invalid();
}
public void accept(Visitor v) { v.visitArray(this); }
public void traverse(ArrayTraverser at) {
for (int i = 0; i < used; i++) {
- at.entry(i, values[i]);
+ at.entry(i, impl.get(i));
}
}
- private void grow() {
- Value[] v = values;
- capacity = (capacity << 1);
- values = new Value[capacity];
- System.arraycopy(v, 0, values, 0, used);
- }
-
protected Value addLeaf(Value value) {
- if (used == capacity) {
- grow();
- }
- values[used++] = value;
- return value;
+ impl.prepareFor(this, value.type());
+ return impl.add(value, used++);
}
public Value addArray() { return addLeaf(new ArrayValue(names)); }
public Value addObject() { return addLeaf(new ObjectValue(names)); }
-
}