@@ -57,47 +57,58 @@ public static ByteString encodeVectorMulti(float[][] vectors) {
5757 }
5858
5959 /**
60- * Decode ByteString to float[].
60+ * Decode ByteString to {@code float[]} .
6161 *
6262 * @throws IllegalArgumentException if ByteString size is not
6363 * a multiple of {@link Float#BYTES}.
6464 */
6565 public static float [] decodeVectorSingle (ByteString bs ) {
6666 if (bs .size () % Float .BYTES != 0 ) {
6767 throw new IllegalArgumentException (
68- "ByteString is size " + bs .size () + ", not a multiple of " + String .valueOf (Float .BYTES ) + " (Float.BYTES)" );
68+ "ByteString size " + bs .size () + " is not a multiple of " + String .valueOf (Float .BYTES ) + " (Float.BYTES)" );
6969 }
7070 float [] vector = new float [bs .size () / Float .BYTES ];
7171 bs .asReadOnlyByteBuffer ().order (BYTE_ORDER ).asFloatBuffer ().get (vector );
7272 return vector ;
7373 }
7474
7575 /**
76- * Decode ByteString to float[][].
76+ * Decode ByteString to {@code float[][]} .
7777 *
78- * @throws IllegalArgumentException if ByteString size is not
79- * a multiple of {@link Float#BYTES}.
78+ * <p>
79+ * The expected structure of the byte string of total size N is:
80+ * <ul>
81+ * <li>[2 bytes]: dimensionality of the inner vector ({@code dim})
82+ * <li>[N-2 bytes]: concatenated inner vectors. N-2 must be a multiple of
83+ * {@code Float.BYTES * dim}
84+ * </ul>
85+ *
86+ * @throws IllegalArgumentException if ByteString is not of a valid size.
8087 */
8188 public static float [][] decodeVectorMulti (ByteString bs ) {
8289 if (bs == null || bs .size () == 0 ) {
8390 return new float [0 ][0 ];
8491 }
8592
8693 ByteBuffer buf = bs .asReadOnlyByteBuffer ().order (BYTE_ORDER );
94+ short dim = buf .getShort (); // advances current position
95+ if (dim == 0 ) {
96+ return new float [0 ][0 ];
97+ }
8798
88- // Dimensions are encoded in the first 2 bytes.
89- short dimensions = buf . getShort (); // advances current position
90-
91- // TODO: throw IllegalArgumentException if fbuf.remaining not a multile of
92- // Float.BYTES
93- FloatBuffer fbuf = buf . asFloatBuffer ();
94- int n = fbuf .remaining () / dimensions ; // fbuf size is buf / Float.BYTES
99+ FloatBuffer fbuf = buf . asFloatBuffer (); // fbuf size is buf / Float.BYTES
100+ if ( fbuf . remaining () % dim != 0 ) {
101+ throw new IllegalArgumentException (
102+ "Remaing ByteString size " + fbuf .remaining () + " is not a multiple of " + dim
103+ + " (dim)" );
104+ }
105+ int n = fbuf .remaining () / dim ;
95106
96107 // Reading from buffer advances current position,
97108 // so we always read from offset=0.
98- float [][] vectors = new float [n ][dimensions ];
109+ float [][] vectors = new float [n ][dim ];
99110 for (int i = 0 ; i < n ; i ++) {
100- fbuf .get (vectors [i ], 0 , dimensions );
111+ fbuf .get (vectors [i ], 0 , dim );
101112 }
102113 return vectors ;
103114 }
0 commit comments