diff options
author | Jon Bratseth <bratseth@gmail.com> | 2023-03-20 11:26:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-20 11:26:26 +0100 |
commit | 47e7d6a7509c5ba3a339afbaa0f17b16d9b382af (patch) | |
tree | ad511fda70c2bdaffa21311ce3fb069cf95730b3 /vespajlib/src/main | |
parent | 89862f601ce193c1b8aa96d9979ad5ef57c1a505 (diff) | |
parent | 24b297f12cdb8707d15ad554554eaaff76bcbdd3 (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.java | 108 |
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)); } - } |