This is an automated email from the ASF dual-hosted git repository. noble pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push: new c2e8388dc77 SOLR-17588 : javabin must support primitive arrays (#2900) c2e8388dc77 is described below commit c2e8388dc7732ec8f9a51edcb882d9929c47784b 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 77e7186c9de..7373632da28 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 6d02cf82185..3a85f4e0f04 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<>(); @@ -223,6 +237,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)); }