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));
       }

Reply via email to