11package org .fastfilter .xor ;
22
3+ import java .nio .ByteBuffer ;
34import java .util .Arrays ;
4-
55import org .fastfilter .Filter ;
66import org .fastfilter .utils .Hash ;
77
@@ -20,19 +20,25 @@ public class XorBinaryFuse16 implements Filter {
2020 private final short [] fingerprints ;
2121 private long seed ;
2222
23- public XorBinaryFuse16 (int segmentCount , int segmentLength ) {
23+ private XorBinaryFuse16 (int segmentCount , int segmentLength , long seed , short [] fingerprints ) {
2424 if (segmentLength < 0 || Integer .bitCount (segmentLength ) != 1 ) {
2525 throw new IllegalArgumentException ("Segment length needs to be a power of 2, is " + segmentLength );
2626 }
2727 if (segmentCount <= 0 ) {
2828 throw new IllegalArgumentException ("Illegal segment count: " + segmentCount );
2929 }
30- this . segmentLength = segmentLength ;
30+
3131 this .segmentCount = segmentCount ;
32- this .segmentLengthMask = segmentLength - 1 ;
3332 this .segmentCountLength = segmentCount * segmentLength ;
34- this .arrayLength = (segmentCount + ARITY - 1 ) * segmentLength ;
35- this .fingerprints = new short [arrayLength ];
33+ this .segmentLength = segmentLength ;
34+ this .segmentLengthMask = segmentLength - 1 ;
35+ this .arrayLength = fingerprints .length ;
36+ this .fingerprints = fingerprints ;
37+ this .seed = seed ;
38+ }
39+
40+ public XorBinaryFuse16 (int segmentCount , int segmentLength ) {
41+ this (segmentCount , segmentLength , 0L , new short [(segmentCount + ARITY - 1 ) * segmentLength ]);
3642 }
3743
3844 public long getBitCount () {
@@ -204,9 +210,10 @@ private void addAll(long[] keys) {
204210 // It's better fail that either produce non-functional or incorrect filter.
205211 throw new IllegalArgumentException ("could not construct filter" );
206212 }
207- // use a new random numbers
213+ // use a new random number
208214 seed = Hash .randomSeed ();
209215 }
216+
210217 alone = null ;
211218 t2count = null ;
212219 t2hash = null ;
@@ -258,4 +265,51 @@ private short fingerprint(long hash) {
258265 return (short ) hash ;
259266 }
260267
261- }
268+ @ Override
269+ public int getSerializedSize () {
270+ return 2 * Integer .BYTES + Long .BYTES + Integer .BYTES + fingerprints .length * Short .BYTES ;
271+ }
272+
273+ @ Override
274+ public void serialize (ByteBuffer buffer ) {
275+ if (buffer .remaining () < getSerializedSize ()) {
276+ throw new IllegalArgumentException ("Buffer too small" );
277+ }
278+
279+ buffer .putInt (segmentLength );
280+ buffer .putInt (segmentCountLength );
281+ buffer .putLong (seed );
282+ buffer .putInt (fingerprints .length );
283+ for (final short fp : fingerprints ) {
284+ buffer .putShort (fp );
285+ }
286+ }
287+
288+ public static XorBinaryFuse16 deserialize (ByteBuffer buffer ) {
289+ // Check minimum size for header (2 ints + 1 long + 1 int for length)
290+ if (buffer .remaining () < 2 * Integer .BYTES + Long .BYTES + Integer .BYTES ) {
291+ throw new IllegalArgumentException ("Buffer too small" );
292+ }
293+
294+ final int segmentLength = buffer .getInt ();
295+ final int segmentCountLength = buffer .getInt ();
296+ final long seed = buffer .getLong ();
297+
298+ final int len = buffer .getInt ();
299+
300+ // Check if buffer has enough bytes for all fingerprints
301+ if (buffer .remaining () < len * Short .BYTES ) {
302+ throw new IllegalArgumentException ("Buffer too small" );
303+ }
304+
305+ final short [] fingerprints = new short [len ];
306+ for (int i = 0 ; i < len ; i ++) {
307+ fingerprints [i ] = buffer .getShort ();
308+ }
309+
310+ // Calculate segmentCount from segmentCountLength and segmentLength
311+ final int segmentCount = segmentCountLength / segmentLength ;
312+
313+ return new XorBinaryFuse16 (segmentCount , segmentLength , seed , fingerprints );
314+ }
315+ }
0 commit comments