From 8b98b74f3abca4bbdeeb3c04fe18f0b72926749b Mon Sep 17 00:00:00 2001 From: wuzq Date: Fri, 13 Jan 2023 11:31:43 +0800 Subject: [PATCH] In version 0.9.36, RoaringBitmap fixed compatibility issues with CRoaring --- .../client/data/ClickHouseBitmap.java | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseBitmap.java b/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseBitmap.java index 1e5dd0247..505eea50e 100644 --- a/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseBitmap.java +++ b/clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseBitmap.java @@ -177,11 +177,16 @@ public void serialize(ByteBuffer buffer) { } byte[] bytes = bas.toByteArray(); - for (int i = 4; i > 0; i--) { - buffer.put(bytes[i]); + if (Roaring64NavigableMap.SERIALIZATION_MODE == Roaring64NavigableMap.SERIALIZATION_MODE_PORTABLE) { + // In Roaring64NavigableMap SERIALIZATION_MODE_PORTABLE mode, binary serialization data consistent with the CRoaring. No other special processing is required + buffer.put(bytes, 0, size); + } else { + for (int i = 4; i > 0; i--) { + buffer.put(bytes[i]); + } + buffer.putInt(0); + buffer.put(bytes, 5, size - 5); } - buffer.putInt(0); - buffer.put(bytes, 5, size - 5); } catch (IOException e) { throw new IllegalStateException("Failed to serialize given bitmap", e); } @@ -362,18 +367,23 @@ public static ClickHouseBitmap deserialize(DataInputStream in, ClickHouseDataTyp b.deserialize(flip(newBuffer(len).put(bytes))); rb = ClickHouseBitmap.wrap(b, innerType); } else { - // TODO implement a wrapper of DataInput to get rid of byte array here - bytes[0] = (byte) 0; // always unsigned - // read map size in big-endian byte order - for (int i = 4; i > 0; i--) { - bytes[i] = in.readByte(); + if (Roaring64NavigableMap.SERIALIZATION_MODE == Roaring64NavigableMap.SERIALIZATION_MODE_PORTABLE) { + // In Roaring64NavigableMap SERIALIZATION_MODE_PORTABLE mode, binary serialization data consistent with the CRoaring + in.readFully(bytes, 0 ,len); + } else { + // TODO implement a wrapper of DataInput to get rid of byte array here + bytes[0] = (byte) 0; // always unsigned + // read map size in big-endian byte order + for (int i = 4; i > 0; i--) { + bytes[i] = in.readByte(); + } + if (in.readByte() != 0 || in.readByte() != 0 || in.readByte() != 0 || in.readByte() != 0) { + throw new IllegalStateException( + "Not able to deserialize ClickHouseBitmap for too many bitmaps(>" + 0xFFFFFFFFL + ")!"); + } + // read the rest + in.readFully(bytes, 5, len - 8); } - if (in.readByte() != 0 || in.readByte() != 0 || in.readByte() != 0 || in.readByte() != 0) { // NOSONAR - throw new IllegalStateException( - "Not able to deserialize ClickHouseBitmap for too many bitmaps(>" + 0xFFFFFFFFL + ")!"); - } - // read the rest - in.readFully(bytes, 5, len - 8); Roaring64NavigableMap b = new Roaring64NavigableMap(); b.deserialize(new DataInputStream(new ByteArrayInputStream(bytes))); rb = ClickHouseBitmap.wrap(b, innerType); @@ -593,12 +603,18 @@ public ByteBuffer toByteBuffer() { BinaryStreamUtils.writeVarInt(buf, size); serialize(buf); } else { // 64 - // 1) deduct one to exclude the leading byte - boolean flag, see below: - // https://github.com/RoaringBitmap/RoaringBitmap/blob/0.9.9/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java#L1107 - // 2) add 4 bytes because CRoaring uses long to store count of 32-bit bitmaps, - // while Java uses int - see - // https://github.com/RoaringBitmap/CRoaring/blob/v0.2.66/cpp/roaring64map.hh#L597 - long size = serializedSizeInBytesAsLong() - 1 + 4; + long size = 0; + if (Roaring64NavigableMap.SERIALIZATION_MODE == Roaring64NavigableMap.SERIALIZATION_MODE_PORTABLE) { + // In Roaring64NavigableMap SERIALIZATION_MODE_PORTABLE mode, binary serialization data consistent with the CRoaring + size = serializedSizeInBytesAsLong(); + } else { + // 1) deduct one to exclude the leading byte - boolean flag, see below: + // https://github.com/RoaringBitmap/RoaringBitmap/blob/0.9.9/RoaringBitmap/src/main/java/org/roaringbitmap/longlong/Roaring64NavigableMap.java#L1107 + // 2) add 4 bytes because CRoaring uses long to store count of 32-bit bitmaps, + // while Java uses int - see + // https://github.com/RoaringBitmap/CRoaring/blob/v0.2.66/cpp/roaring64map.hh#L597 + size = serializedSizeInBytesAsLong() - 1 + 4; + } int varIntSize = BinaryStreamUtils.getVarLongSize(size); // TODO add serialize(DataOutput) to handle more int intSize = (int) size;