This is an automated email from the ASF dual-hosted git repository. noble pushed a commit to branch branch_9x in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push: new fa52b8b8c91 SOLR-17588 : javabin must support primitive arrays (#2900) fa52b8b8c91 is described below commit fa52b8b8c91e0d8f10f69259b482cf8849460b9c Author: Noble Paul <noblep...@users.noreply.github.com> AuthorDate: Tue Dec 24 17:49:38 2024 +1100 SOLR-17588 : javabin must support primitive arrays (#2900) --- .../org/apache/solr/common/util/JavaBinCodec.java | 144 +++++++++++++++++++++ .../apache/solr/common/util/TestJavaBinCodec.java | 31 +++++ 2 files changed, 175 insertions(+) diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java index 9a16ea5abbc..04c8512e614 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java @@ -103,6 +103,7 @@ public class JavaBinCodec implements PushWriter { MAP_ENTRY = 19, UUID = 20, // This is reserved to be used only in LogCodec // types that combine tag + length (or other info) in a single byte + PRIMITIVE_ARR = 21, TAG_AND_LEN = (byte) (1 << 5), STR = (byte) (1 << 5), SINT = (byte) (2 << 5), @@ -348,6 +349,8 @@ public class JavaBinCodec implements PushWriter { return readMapEntry(dis); case MAP_ENTRY_ITER: return readMapIter(dis); + case PRIMITIVE_ARR: + return readPrimitiveArray(dis); } throw new RuntimeException("Unknown type " + tagByte); @@ -438,9 +441,150 @@ public class JavaBinCodec implements PushWriter { writeBoolean(((AtomicBoolean) val).get()); return true; } + if (val instanceof float[] ff) { + writeFloatArr(ff); + return true; + } + if (val instanceof int[] ii) { + writeIntArr(ii); + return true; + } + if (val instanceof long[] ll) { + writeLongArr(ll); + return true; + } + if (val instanceof double[] dd) { + writeDoubleArr(dd); + return true; + } + if (val instanceof short[] ss) { + writeShortArr(ss); + return true; + } + if (val instanceof boolean[] bb) { + writeBoolArr(bb); + return true; + } return false; } + public Object readPrimitiveArray(DataInputInputStream dis) throws IOException { + tagByte = dis.readByte(); + int len = readVInt(dis); + switch (tagByte) { + case FLOAT: + { + float[] v = new float[len]; + for (int i = 0; i < len; i++) { + v[i] = dis.readFloat(); + } + return v; + } + case INT: + { + int[] v = new int[len]; + for (int i = 0; i < len; i++) { + v[i] = dis.readInt(); + } + return v; + } + + case LONG: + { + long[] v = new long[len]; + for (int i = 0; i < len; i++) { + v[i] = dis.readLong(); + } + return v; + } + case DOUBLE: + { + double[] v = new double[len]; + for (int i = 0; i < len; i++) { + v[i] = dis.readDouble(); + } + return v; + } + case SHORT: + { + short[] v = new short[len]; + for (int i = 0; i < len; i++) { + v[i] = dis.readShort(); + } + return v; + } + case BOOL_TRUE: + case BOOL_FALSE: + { + boolean[] v = new boolean[len]; + for (int i = 0; i < len; i++) { + byte b = dis.readByte(); + v[i] = b == BOOL_FALSE ? false : true; + } + return v; + } + case BYTE: + { + // it should be possible to serialize byte[] in the new format as well + byte[] v = new byte[len]; + dis.readFully(v); + return v; + } + default: + { + throw new RuntimeException("Invalid type : " + tagByte); + } + } + } + + public void writePrimitiveArrHeader(byte tag, int len) throws IOException { + writeTag(PRIMITIVE_ARR); + writeTag(tag); + writeVInt(len, daos); + } + + public void writeFloatArr(float[] vals) throws IOException { + writePrimitiveArrHeader(FLOAT, vals.length); + for (float f : vals) { + daos.writeFloat(f); + } + } + + public void writeIntArr(int[] vals) throws IOException { + writePrimitiveArrHeader(INT, vals.length); + for (int i : vals) { + daos.writeInt(i); + } + } + + public void writeDoubleArr(double[] vals) throws IOException { + writePrimitiveArrHeader(DOUBLE, vals.length); + for (double d : vals) { + daos.writeDouble(d); + } + } + + public void writeLongArr(long[] vals) throws IOException { + writePrimitiveArrHeader(LONG, vals.length); + for (long l : vals) { + daos.writeLong(l); + } + } + + public void writeBoolArr(boolean[] vals) throws IOException { + writePrimitiveArrHeader(BOOL_TRUE, vals.length); + for (boolean b : vals) { + writeBoolean(b); + } + } + + public void writeShortArr(short[] vals) throws IOException { + writePrimitiveArrHeader(SHORT, vals.length); + for (short l : vals) { + daos.writeShort(l); + } + } + public class BinEntryWriter implements MapWriter.EntryWriter { @Override public MapWriter.EntryWriter put(CharSequence k, Object v) throws IOException { diff --git a/solr/solrj/src/test/org/apache/solr/common/util/TestJavaBinCodec.java b/solr/solrj/src/test/org/apache/solr/common/util/TestJavaBinCodec.java index baf36a1cc89..12e3dbb9db9 100644 --- a/solr/solrj/src/test/org/apache/solr/common/util/TestJavaBinCodec.java +++ b/solr/solrj/src/test/org/apache/solr/common/util/TestJavaBinCodec.java @@ -108,6 +108,20 @@ public class TestJavaBinCodec extends SolrTestCaseJ4 { return parentDocument; } + @Test + public void testPrimitiveArrays() throws Exception { + List<Object> types = new ArrayList<>(); + + types.add(new float[] {1.0678f, 4.094565f, 0.000456f}); + types.add(new double[] {1.0678d, 4.094565d, 0.000456d}); + types.add(new int[] {145543, 4546354, 9789857}); + types.add(new long[] {145543L, 4546354L, 9789857L}); + types.add(new short[] {43, 454, 857}); + types.add(new boolean[] {true, true, false}); + + compareObjects((List<?>) getObject(getBytes(types)), types); + } + private List<Object> generateAllDataTypes() { List<Object> types = new ArrayList<>(); @@ -225,6 +239,23 @@ public class TestJavaBinCodec extends SolrTestCaseJ4 { } else if (unmarshalledObj.get(i) instanceof SolrInputField && matchObj.get(i) instanceof SolrInputField) { assertTrue(assertSolrInputFieldEquals(unmarshalledObj.get(i), matchObj.get(i))); + } else if (unmarshalledObj.get(i) instanceof float[] a + && matchObj.get(i) instanceof float[] e) { + assertArrayEquals(e, a, 0.000000f); + } else if (unmarshalledObj.get(i) instanceof double[] a + && matchObj.get(i) instanceof double[] e) { + assertArrayEquals(e, a, 0.000000d); + } else if (unmarshalledObj.get(i) instanceof long[] a + && matchObj.get(i) instanceof long[] e) { + assertArrayEquals(e, a); + } else if (unmarshalledObj.get(i) instanceof int[] a && matchObj.get(i) instanceof int[] e) { + assertArrayEquals(e, a); + } else if (unmarshalledObj.get(i) instanceof short[] a + && matchObj.get(i) instanceof short[] e) { + assertArrayEquals(e, a); + } else if (unmarshalledObj.get(i) instanceof boolean[] a + && matchObj.get(i) instanceof boolean[] e) { + assertArrayEquals(e, a); } else { assertEquals(unmarshalledObj.get(i), matchObj.get(i)); }